2013-11-04 4 views
0

에서 텍스트를 구문 분석 나는 탭으로 구분 된 파일 1이 :문자열

20 50 80 110 
    520 590 700 770 
    410 440 20 50 
    300 340 410 440 

읽기 및 배열에 넣어 : 이제

while(<INPUT>) 
{ 
    chomp; 
    push @inputarray, $_; 
} 

내가 다른 파일 2 통해 반복 해요 :

20, 410, 700 
    80, 520 
    300 

file2의 각 줄 번호는 @inputarray에서 해당 번호를 검색하려고합니다. 그것이 존재한다면, 나는 그 뒤에 오는 대응하는 숫자를 움켜 잡고 싶다. 예를 들어, 숫자 20의 경우 숫자 50을 얻고 싶습니다. @inputarray의 배열 요소로 존재하는 문자열의 탭으로 계속 구분되어 있다고 가정합니다. GREP이 발견되면

while(my $line = <INPUT2>) 
{ 
    chomp $line; 
    my @linearray = split("\t", $line); 
    foreach my $start (@linearray) 
    { 
    if (grep ($start, @inputarray)) 
    { 
     #want to grab the corresponding number 
    } 
    } 
} 

, 나는 아마 SUBSTR 함수를 사용하여 해당 번호를 추출하는 숫자의 위치를 ​​찾기 위해 그 배열 요소를 잡아하는 방법을 모르겠어요. grep이 발견 한 배열 요소를 어떻게 잡아낼 수 있습니까?

소망하는 출력은 다음과 같습니다 번 입력을 읽을 수는 있지만 번호를 많이 확인하려면

line1: 
20 50 
410 440 
700 770 

line2: 
80 110 
520 590 

line3: 
300 340 
+0

file2가 file1의 두 번째 열의 숫자를 포함하고있을 가능성이 있습니까? 예를 들어 50,440,110도 마찬가지예요? – Samiron

+0

File2는 file1의 2 열과 4 열에있는 숫자 만 포함합니다. – user2674514

+0

@ user2674514 : 당신의 예제는 * file2 *가 * file1 *의 * column1 *에서 오는 숫자 인'20, 410, 700'을 포함하고 있음을 보여줍니다. 'column 2 and 4'는 마지막 코멘트의 오타입니까? – Samiron

답변

0

, 당신은 split 개별 숫자로 입력 라인에 더 나을 수 있습니다. 그런 다음 각 숫자를 값으로 다음 숫자와 함께 해시에 키로 추가하십시오. 읽기가 느려지고 더 많은 메모리가 필요하지만 두 번째 부분은 다음 숫자를 확인하려는 경우 exist과 해시의 특성 덕분입니다.

정확한 질문을 이해한다면 큰 해시를 하나만 사용할 수 있습니다. 물론 모든 숫자에 항상 같은 숫자가 올 것이라고 가정합니다.

2

IMHO, file1의 숫자를 해시에 저장하는 것이 가장 좋습니다. 당신은 당신이 코드의 샘플 조각

my %inputarray; 
while(<INPUT>) 
{ 
    my @numbers = split $_; 
    my $length = scalar $numbers; 
    # For $i = 0 to $i < $length; 
    # $inputarray{$numbers[$i]} = $numbers[$i+1]; 
    # $i+=2; 
} 

같이 위의 루프의 시연 될 것입니다

{ 
    '20' => '50', 
    '80' => '110', 
    '520'=> '590', 
    '700'=> '770', 
    '410'=> '440', 
    '20' => '50', 
    '300'=> '340', 
    '410' => '440' 
} 

아래 같은 것을 가질 수 위의 규정 된 파일 1의 예 clontent를 참조

index: 0  1 2 3 
numbers: 20 50 80 110 

first iteration: $i=0 
    $inputarray{$numbers[0]} = $numbers[1]; 
    $i = 2; #$i += 2; 
second iteration: $i=2 
    $inputarray{$numbers[2]} = $numbers[3]; 

그리고 file2를 구문 분석하는 동안 key의 번호를 %inputarray으로 처리하면됩니다.

+0

file2에 임의의 숫자가 포함될 수 있으면'$ i + = 1'. 그리고 아마도'@ numbers'에'$ i' 번째 요소가 있는지 확인해야합니다. – DeVadder

+0

@DeVadder : 각 반복에 대해 $ i (key)와 $ i + 1 (value)가'% inpurarray '에 사용 중이므로'$ i + = 2 '가 아니어야합니다. 그래서 다음 반복에서는'$ i + 2'에서 시작할 필요가 있습니다. 내가 당신이 지적하고 싶었던 것을 놓쳤습니까? – Samiron

+1

DeVadder와 Samiron에게 감사드립니다. 첫 번째 파일을 해시에 넣고 키 값을 검색하는 것이 올바른 생각이었습니다. – user2674514

1

나는 이것이 당신이 원하는 것에 가깝다고 믿습니다.

#!/usr/bin/perl -w 

my %follows; 

open my $file1, "<", $ARGV[0] or die "could not open $ARGV[0]: $!\n"; 

while (<$file1>) 
{ 
    chomp; 

    my $prev = undef; 

    foreach my $curr (split /\s+/) 
    { 
     $follows{$prev} = $curr if ($prev); 
     $prev = $curr; 
    } 
} 

close $file1; 

open my $file2, "<", $ARGV[1] or die "could not open $ARGV[1]: $!\n"; 
my $lineno = 1; 

while (<$file2>) 
{ 
    chomp; 
    print "line $lineno\n"; 
    $lineno++; 

    foreach my $val (split /,\s+/, $_) 
    { 
     print $val, " ", ($follows{$val} // "no match"), "\n"; 
    } 
    print "\n"; 
} 

당신은 단지 숫자, 당신은 첫 번째 while 루프에서 논리를 변경해야 계정에 쌍의 경계를 복용하지 않고 어떤 다른 숫자에 따라 어떤 보는 반대로, file1에서 숫자를 고려할 경우

약간.

#!/usr/bin/perl -w 

my %follows; 

open my $file1, "<", $ARGV[0] or die "could not open $ARGV[0]: $!\n"; 

while (<$file1>) 
{ 
    chomp; 

    my $line = $_; 

    while ($line =~ s/(\S+)\s+(\S+)\s*//) 
    { 
     $follows{$1} = $2; 
    } 
} 

close $file1; 

open my $file2, "<", $ARGV[1] or die "could not open $ARGV[1]: $!\n"; 
my $lineno = 1; 

while (<$file2>) 
{ 
    chomp; 
    print "line $lineno\n"; 
    $lineno++; 

    foreach my $val (split /,\s+/, $_) 
    { 
     print $val, " ", ($follows{$val} // "no match"), "\n"; 
    } 
    print "\n"; 
} 
+0

위의 두 스크립트 모두 테스트 데이터와 일치하는 출력을 생성합니다. 좀 더 철저한 테스트를 거쳐 어떤 스크립트가 사용자의 요구를 충족시키는 지 결정해야합니다. –