2011-02-02 3 views
1

탭으로 구분 된 여러 데이터 파일이 있습니다. 이 데이터 파일의 특정 열 (25 열)의 모든 고유 값을 추출하여 추가 처리를 위해 출력 파일에이 값을 기록해야합니다. Perl에서 어떻게 할 수 있습니까? 동일한 폴더에서 여러 파일을 고려해야한다는 것을 기억하십시오.Perl의 여러 파일에서 고유 값 추출

편집 : 지금까지 해본 코드는 이와 같습니다.

#!/usr/bin/perl     

use warnings; 
use strict; 

my @hhfilelist = glob "*.hh3"; 

for my $f (@hhfilelist) { 
    open F, $f || die "Cannot open $f: $!"; 
    while (<F>) { 
    chomp; 
    my @line = split /\t/; 

    print "field is $line[24]\n"; 
    } 
    close (F); 
} 

질문은 어떻게하면 각 파일의 각 줄을 읽을 때 고유 한 값의 해시/배열을 효율적으로 만들 수 있습니까? 또는 전체 배열을 채우고 중복을 제거하면 더 빠릅니까?

+0

@davorg 잘 난 기본적인 문제 자체에 붙어있어. 먼저 여러 파일을 한 번에 하나씩 읽는 방법. 다음 파일은 각 파일을 읽을 때 고유 한 값만 고려합니다. Find :: File 패키지를 사용할 수 있습니다. – sfactor

+0

@DVK yes는 이미 Perl에있는 더 큰 코드의 일부입니다. – sfactor

+0

보통 X로 구분 된 파일을 구문 분석 할 때 split을 사용해서는 안됩니다. 가장 사소한 경우를 제외하고는 충분하지 않습니다. 예 : 필드 안에있는 X (분리 기호) 나 따옴표로 묶인 필드는 처리하지 않습니다. 평범한 경우에는 작동하지만, glob() 함수를 성공적으로 사용했습니다. – DVK

답변

2
perl -F/\\t/ -ane 'print"$F[24]\n" unless $seen{$F[24]}++' inputs > output 

perl -F/\\t/ -ane 'print"$F[24]\n" unless $seen{$F[24]}++' *.hh3 > output 

명령 행마다 입력 파일의 라인마다 반복 의미 -F/\\t/ -an 스위치를 파일에 기록하고 배열 @F에 탭 캐릭터 라인을 분할.

$F[24]

$seen{...} 값은 이미 관찰되었는지 추적하는 해시 테이블 인 (24 번째와 25 번째 탭 문자 사이의) 각 행의 25 번째 필드의 값을 말한다. 값이 처음 발견되면 $seen{VALUE}은 0이므로 Perl은 print"$F[24]\n" 문을 실행합니다. 그 값이 관찰 될 때마다 $seen{VALUE}은 0이 아니며 명령문이 실행되지 않습니다. 이렇게하면 각 고유 값이 정확히 한 번 인쇄됩니다. 당신의 큰 스크립트에 유사한 맥락에서


:

my @hhfilelist = glob "*.hh3"; 
my %values_in_field_25 =(); 
for my $f (@hhfilelist) { 
    open F, $f || die "Cannot open $f: $!"; 
    while (<F>) { 
    my @F = split /\t/; 
    $values_in_field_25{$F[24]} = 1; 
    } 
    close (F); 
} 

my @unique_values_in_field_25 = keys %values_in_field_25; # or sort keys ... 
3

Perl 솔루션의 경우 Text::CSV 모듈을 사용하여 플랫 (X 분리 된) 파일을 구문 분석하십시오. 생성자는 분리 문자를 지정하는 매개 변수를 허용합니다. 루프의 모든 파일에 대해 파일 목록이 glob() (특정 디렉토리의 파일 인 경우) 또는 File::Find (하위 디렉토리의 경우)

그런 다음 각 행에 대해 25 열을 해시.

예. 값을 검색 한 후 :

$colref = $csv->getline($io); 
$unique_values_hash{ $colref->[24] } = 1; 

그런 다음 해시 키를 반복하고 파일로 인쇄하십시오. 비 펄 쉘 솔루션을


, 당신은 간단하게 수행 할 수 있습니다

cat MyFile_pattern | awk -F'\t' 'print $25' |sort -u > MyUniqueValuesFile 

당신은 cut

awk을 대체 할 수있는 비 펄 솔루션에만 작동 있습니다 경우 파일 돈 ' 필드 자체에 TAB을 포함하고 열은 따옴표로 묶이지 않습니다. 문제를 처리하는 방법에

+0

하지만 난 perl에 익숙하지 않아서, 당신이 해쉬에 값을 저장하고 그것을 반복하는 abt를 말하는 부분을 다소 혼란스럽게 생각하니? 어떻게 말해 줄 수 있니? – sfactor

+0

@sfactor - 업데이트 – DVK

3

몇 가지 팁 :

  • 디렉토리 내에서 파일을 찾기 위해 파일을
    • 찾기를 glob 사용 glob '.* *'
    • 을 디렉토리 트리 내에서 파일을 찾기 위해, File::Find를 사용 ' s find 기능
  • 각 파일을 열고 Text::CSV 구분자로서 \t 문자 추출 값을 원하고
+0

모두를 참조하십시오.하지만 OP에는 다른 하나의 구체적인 예가 필요할 수 있습니다. – zanlok