텍스트 파일 테이블 구문 분석 및 정보 집계

텍스트 파일 테이블 구문 분석 및 정보 집계

공백으로 구분된 다음 열을 포함하는 긴 텍스트 파일이 있습니다.

Id            Pos Ref  Var  Cn   SF:R1   SR  He  Ho NC       
cm|371443199  22  G     A    R   Pass:8   0   1  0  0       
cm|371443199  25  C     A    M   Pass:13  0   0  1  0
cm|371443199  22  G     A    R   Pass:8   0   1  0  0        
cm|367079424  17  C     G    S   Pass:19  0   0  1  0      
cm|371443198  17  G     A    R   Pass:18  0   1  0  0       
cm|367079424  17  G     A    R   Pass:18  0   0  1  0 

개수와 함께 각 고유 ID를 나열하는 테이블을 생성하고 싶습니다.

  • 이 ID는 몇 번이나 나타납니까?
  • 통과한 행 수(6열)
  • 얼마나 많은 것이 가치있는가 He(8열)
  • 얼마나 많은 것이 가치있는가 Ho(9열)

이 경우:

Id            CountId  Countpass   CountHe CountHO
cm|371443199   3        3          2        1
cm|367079424   2        2          0        2

이 테이블을 어떻게 생성할 수 있나요?

답변1

perl질문의 내용을 포함하기 위해 가상의 한 가지 방법을 사용합니다 infile(ID를 저장하기 위해 해시를 사용하고 있으므로 ID가 출력에서 ​​반드시 동일한 순서일 필요는 없습니다).

콘텐츠 script.pl:

use strict;
use warnings;

my (%data);

while ( <> ) { 

    ## Omit header.
    next if $. == 1;

    ## Remove last '\n'.
    chomp;

    ## Split line in spaces.
    my @f = split;

    ## If this ID exists, get previously values and add values of this
    ## line to them. Otherwise, begin to count now.
    my @counts = exists $data{ $f[0] } ? @{ $data{ $f[0] } } : (); 
    $counts[0]++;
    $counts[1]++ if substr( $f[5], 0, 4 ) eq q|Pass|;
    $counts[2] += $f[7];
    $counts[3] += $f[8];
    splice @{ $data{ $f[0] } }, 0, @{ $data{ $f[0] } }, @counts; 
}

## Format output.
my $print_format = qq|%-15s %-10s %-12s %-10s %-10s\n|;

## Print header.
printf $print_format, qw|Id CountId CountPass CountHe CountHo|;

## For every ID saved in the hash print acumulated values.
for my $id ( keys %data ) { 
    printf $print_format, $id, @{ $data{ $id } };
}

다음과 같이 실행하세요:

perl script.pl infile

다음 출력으로:

Id              CountId    CountPass    CountHe    CountHo   
cm|371443198    1          1            1          0         
cm|371443199    3          3            2          1         
cm|367079424    2          2            0          2

답변2

여기에 해결책이 있습니다. awk4개의 배열을 사용하여 필요한 4가지 정보를 계산하세요. 그런 다음 출력을 awk여기에 입력하여 column열을 잘 정렬합니다. (참고로 이 작업은 를 awk사용하여 수행 할 수도 있습니다 printf.)

awk 'NR>1 {
    id[$1]++
    if($6 ~ /Pass/) pass[$1]++
    if($8 ~ /1/) he[$1]++
    if($9 ~ /1/) ho[$1]++
} 
END {
   print "Id CountId Countpass CountHe CountHO"
   for(i in id)
      print i" "id[i]" "(pass[i]?pass[i]:0)" "(he[i]?he[i]:0)" "(ho[i]?ho[i]:0)
}' input.txt | column -t

산출:

Id            CountId  Countpass  CountHe  CountHO
cm|371443198  1        1          1        0
cm|371443199  3        3          2        1
cm|367079424  2        2          0        2

관련 정보