사용join

사용join

SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab SRR3384744.Gene.out.tab이 순서대로 여러 개의 파일과 더 많은 파일이 있습니다 . 이 파일에서 첫 번째와 네 번째 열을 추출하여 출력 파일에 저장합니다. 내 스크립트가 새 파일을 읽을 때 각 파일 끝에 데이터를 추가하는 대신 탭으로 구분된 방식으로 데이터를 추출해야 하는지 확인하려고 합니다.

입력 파일:

SRR3384742.Gene.out.tab

N_unmapped      313860  313860  313860
N_multimapping  5786679 5786679 5786679
N_noFeature     286816  31696770        438410
N_ambiguous     1283487 32117   65902
AT1G01010       301     0       301
AT1G01020       623     1       622
AT1G03987       5       5       0
AT1G01030       151     2       149

SRR3384743.Gene.out.tab

N_unmapped      780346  780346  780346
N_multimapping  4621162 4621162 4621162
N_noFeature     182428  28470016        362650
N_ambiguous     1451612 43059   117293
AT1G01010       154     3       151
AT1G01020       685     2       683
AT1G03987       0       0       0
AT1G01030       63      0       63

내가 얻는 결과는 다음과 같습니다.

SRR3384742.Gene.out.tab 
AT1G01010       301
AT1G01020       622
AT1G03987       0
AT1G01030       149
SRR3384743.Gene.out.tab 
AT1G01010       151
AT1G01020       683
AT1G03987       0
AT1G01030       63

원하는 출력:

SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab 
AT1G01010       301     151
AT1G01020       622     683
AT1G03987       0       0
AT1G01030       149     63

다음 스크립트를 시도했습니다.

for sample in *Gene.out.tab; do echo -en $sample "\n"; awk 'NR>4 {print $1 "\t" $4}' $sample; awk '{print $0, $sample}' OFS='\t' $sample; done > output

답변1

그러면 GNU를 사용하여 주석에 설명된 출력이 제공됩니다 awk.

gawk 'FNR==1{names[c++]=FILENAME}
      FNR>4{ lines[$1] = "x"lines[$1] ? lines[$1]"\t"$4 : $4; } 
      END{ 
            for(i=0;i<=c;i++){
                printf "\t%s",names[i]
            } 
            printf "\n"; 
            for(i in lines){ 
                print i,lines[i]
            }
        }' *Gene.out.tab
    SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab
AT1G01010   301 151
AT1G01020   622 683
AT1G01030   149 63
AT1G03987   0   0

그리고 모든 것을 시각적으로 보기 좋게 정렬하려면 다음을 전달하세요 column.

$ gawk 'FNR==1{names[c++]=FILENAME}FNR>4{ lines[$1] = "x"lines[$1] ? lines[$1]"\t"$4 : $4; } END{ for(i=0;i<=c;i++){printf "\t%s",names[i];} printf "\n"; for(i in lines){ print i,lines[i]}}' *Gene.out.tab | column -s$'\t' -t
            SRR3384742.Gene.out.tab  SRR3384743.Gene.out.tab
AT1G01010   301                      151
AT1G01020   622                      683
AT1G01030   149                      63
AT1G03987   0                        0

FNR현재 처리 중인 파일의 줄 번호를 항상 보유하는 특수 awk 변수입니다. 현재 처리 중인 파일의 이름을 보유하는 FILENAMEGNU 특수 변수입니다 .awk

  • FNR==1{names[c++]=FILENAME}: 이것이 입력 파일의 첫 번째 라인인 경우, 이 변수를 값이 filename 인 배열에 대한 인덱스로 사용 c하고 그 값을 yb 1 ( )만큼 증가시킵니다. 모든 파일이 처리된 후에는 첫 번째 파일 이름, 두 번째 파일 이름 등이 됩니다.namesc++files[0]files[1]

  • FNR>4{ lines[$1] = "x"lines[$1] ? lines[$1]"\t"$4 : $4; }:이것은 다음과 동일합니다:

    if(FNR>4){ 
          if("x"lines[$1]){
           lines[$1]"\t"$4
          else{
              lines[$1] = $4
          }
      }
    

    현재 입력 파일의 줄 번호가 5개 이상인 경우 첫 번째 필드에 배열의 관련 값이 있는지 확인하세요 lines. 사용 여부를 확인하는 "x"lines[$i]이유는 테스트가 거짓이지만 lines[$1]참 이므로 이를 방지할 수 있기 때문입니다. 따라서 값이 있으면 탭과 현재 줄의 두 번째 필드를 여기에 추가하고, 값이 없으면 현재 줄의 네 번째 필드에 설정합니다.0x0x

  • END{ ... }: 모든 입력이 처리된 후 이 작업을 실행합니다.

  • for(i=0;i<=c;i++){printf "\t%s",names[i]}; printf "\n";: names탭 문자 앞에 배열의 각 파일 이름을 인쇄합니다. 우리는 선두 탭이 헤더 행과 콘텐츠의 필드 수를 동일하게 유지하기를 원합니다. 파일 이름을 인쇄한 후 개행 문자를 인쇄합니다.

  • for(i in lines){print i,lines[i]}: 배열의 각 인덱스에 대해 lines인덱스(ID)를 인쇄한 다음 첫 번째 단계에서 저장된 관련 값을 인쇄합니다.

한정: 모든 출력 데이터를 메모리에 저장해야 합니다. 최신 시스템에서는 ID만 저장하고 파일당 ID당 하나의 값만 저장하므로 이는 실제로 문제가 되지 않습니다. 따라서 꽤 괜찮은 시스템에서는 차단하기 전에 많은 입력을 처리할 수 있어야 하지만 그렇지 않을 수도 있습니다. 문제가 된다. 데이터 양이 많아지면 문제가 있는 게 사실이다.

답변2

사용join

join -o '1.1 1.4 2.4' SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab
N_unmapped 313860 780346
N_multimapping 5786679 4621162
N_noFeature 438410 362650
N_ambiguous 65902 117293
AT1G01010 301 151
AT1G01020 622 683
AT1G03987 0 0
AT1G01030 149 63

사용paste

paste나는 이것이 당신이 찾고 있는 것이라고 생각합니다 :

paste <(cut -f 1,4 SRR3384742.Gene.out.tab) <(cut -f4 SRR3384743.Gene.out.tab)
N_unmapped      313860  780346
N_multimapping  5786679 4621162
N_noFeature     438410  362650
N_ambiguous     65902   117293
AT1G01010       301     151
AT1G01020       622     683
AT1G03987       0       0
AT1G01030       149     63

이 솔루션에서는 모든 항목에 다음이 *.tab포함되어야 한다고 가정합니다.

  1. 행 수가 동일합니다.
  2. 같은 순서입니다.

다음은 헤더를 인쇄하고 여러 파일을 처리하는 스크립트입니다.

#!/bin/bash
set -euo pipefail
echo $(printf '%s\t' "$@")
first_file=$1
shift
fifos="<(cut -f1,4 $first_file) "$(printf '<(cut -f4 %s) ' "$@")
eval "paste $fifos"
command *.out.tab
SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab
N_unmapped      313860  780346
N_multimapping  5786679 4621162
N_noFeature     438410  362650
N_ambiguous     65902   117293
AT1G01010       301     151
AT1G01020       622     683
AT1G03987       0       0
AT1G01030       149     63

답변3

for i in *.tab; do echo $i >/tmp/"$i"_out.txt ; awk '/^AT/{print $1,$4}' $i >> /tmp/"$i"_out.txt ; done
paste /tmp/*_out.txt| awk '{$3="";print }'

산출

SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab 
AT1G01010 301  151
AT1G01020 622  683
AT1G03987 0  0
AT1G01030 149  63

관련 정보