2016-07-19 3 views
2

두 가지 유형의 탭으로 구분 된 입력 파일이 있습니다. 첫 번째 열은 첫 번째 열에 세로로 나열된 이름과 후속 열의 숫자 값을 가진 행렬입니다. 두 x 째 유형의 입력에는 첫 x 째 파일 유형의 첫 x 째 열에 같은 이름의 서브 세트가 나열된 단일 C 럼이 들어 있습니다.펄 스크립트 내에서 awk 명령 코딩하기

EX :

Gary 1 2 3 
Yolanda 3 4 5 
Biff 5 6 7 
Hubert 8 9 10 

EX 입력 1 :

Gary 
Biff 

입력 2에 여러 가지 변화가 있지만

입력 2, 단 하나의 입력 1이 있습니다. 필자는 이름이 input2에서 input1로 일치하고 input2의 이름과 input1의 해당 값을 포함하는 출력 파일을 인쇄하기 위해 내장 된 awk 명령이있는 perl 스크립트를 가지고 있습니다.

EX :

Gary 1 2 3 
Biff 5 6 7 

여기 내 코드 출력 파일 :

#!/usr/bin/perl 

use strict; 
use warnings; 

my $dir1 = '../FeatureSelection/Chunks/ArffPreprocessing'; 
my $dir2 = '../DataFiles'; 

opendir(DIR, $dir1) or die $!; 
while (my $file = readdir(DIR)) { 

    # We only want files 
    next unless (-f "$dir1/$file"); 

    # Use a regular expression to find files with .txt 
    next unless ($file =~ m/\.txt/); 

    my @partialName = (split /\./, $file); 

    #The $matchingFile is the file which contains attributes listed vertically, along side their respective data 

    my $matchingFile = "$dir2/input1\.txt "; 

    system("awk -F\"\t\" 'FILENAME==\"$dir1/$file\"{a[\$1]=\$1} FILENAME==\"$matchingFile\"{if(a[\$1]){print \$0}}' $dir1/$file $matchingFile > $dir1/$partialName[0]'\_matched.out' "); 

} 

closedir(DIR); 
exit 0; 

이 라인은 명령 줄에서 작동하지만, 내 펄 스크립트에서 작업을 거부합니다. 그런데

awk -F"\t" 'FILENAME=="input2.txt"{a[$1]=$1} FILENAME=="../../../DataFiles/input1.txt"{if(a[$1]){print $0}}' input2.txt ../../../DataFiles/input1.txt > input2_matched.out 

는 입력 2 파일의 깎아 지른듯한 숫자는 명령을 내 원하는 기능을 수행 할 수있는 펄 스크립트를 활용 한 이유는 엉덩이에 진짜 고통을 propt에서 위의 AWK 라인을 하드 코딩한다 디렉토리의 모든 input2 파일에서 출력 파일의 이름 지정 규칙을 유지하십시오. 유사한 프로그램을 작성 했으므로 구문이

system("awk ...blah blah... "); 

일 수 있고 올바르게 작동하는지 알 수 있습니다.

저는이 문제에 며칠 동안 고생했습니다. 그래서 어떤 도움이라도 대단히 감사 할 것입니다!

+1

에 맞게 조정해야합니다. 그것은 더 빠를 것입니다. – Arijit

+0

해시는 무엇을 의미합니까? –

+1

해시에 대한 훌륭한 문서로이 링크에서 찾을 수 있습니다. http://www.tutorialspoint.com/perl/perl_hashes.htm – Arijit

답변

0

입력 2에는 여러 가지 변형이 있지만 단일 입력 1은 뿐입니다. 필자는 awk 명령이 내장 된 perl 스크립트를 가지고 있는데, 이는 input2에서 이름을 일치 시켜서 input2의 이름과 input1의 해당 값을 포함하는 출력 파일 출력 파일을 인쇄합니다.

나는, 우리의 기능을 발견 가진 {} + 명령 줄을 구축하여 목표를

matcher(){ 
awk 'NR==FNR{input1record[$1]=$0;next} 
    $1 in input1record{print input1record[$1]}' /path/to/input1 "[email protected]" >> /path/to/result 
} 
export -f matcher 
find /path/to/input2_files -type f -name "input2" \ 
    -exec bash -c 'matcher "[email protected]"' _ {} + 

참조

  1. 을 달성하고 서브 쉘 명령을 실행 find + a comparison function을 제안 한 번만이 사건. [ find ] 맨 페이지를 참조하십시오.

  2. 나는 >>을 사용하여 후속 실행의 출력을 출력 파일에 추가했습니다. 원하지 않으면 >을 사용하십시오.

  3. -name와 패턴은 당신이 이런 종류의 문제를 해결하기 위해 해시를 사용하는 것이 좋습니다 수있는 모든 input2 파일 이름

+1

이 접근 방법은 비록 속도면에서'perl'의 어느 곳에서도 짧지는 않을 것입니다. –