Linux의 여러 파일 중에서 필수 열이 포함된 새 파일을 만드는 방법은 무엇입니까?

Linux의 여러 파일 중에서 필수 열이 포함된 새 파일을 만드는 방법은 무엇입니까?

ballgown예제 이름으로 약 1000개의 하위 디렉터리가 있는 디렉터리가 있습니다 . 각 하위 디렉토리마다 파일이 있습니다 t_data.ctab. 파일 이름은 모든 하위 디렉터리에서 동일합니다.

ballgown
      |_______TCGA-A2-A0T3-01A
                   |___________ t_data.ctab
      |_______TCGA-A7-A4SA-01A
                   |___________ t_data.ctab
      |_______TCGA-A7-A6VW-01A
                   |___________ t_data.ctab

위와 같은 ballgown하위 디렉터리가 1000개 있습니다 . 1000개 하위 디렉터리 모두에 있는 파일은 t_data.ctab다음과 같으며 열은 다음과 같습니다.

t_id    chr     strand  start   end     t_name  num_exons       length  gene_id gene_name       cov     FPKM
1       1       -       10060   10614   MSTRG.1.1       1       555     MSTRG.1 .       0.000000        0.000000
2       1       +       11140   30023   MSTRG.10.1      12      3981    MSTRG.10        .       2.052715        0.284182
3       1       -       11694   29342   MSTRG.11.1      8       6356    MSTRG.11        .       0.557588        0.077194
4       1       +       11869   14409   ENST00000456328.2       3       1657    MSTRG.10        DDX11L1 0.000000        0.000000
5       1       +       11937   29347   MSTRG.10.3      12      3544    MSTRG.10        .       0.000000        0.000000
6       1       -       11959   30203   MSTRG.11.2      11      4547    MSTRG.11        .       0.369929        0.051214
7       1       +       12010   13670   ENST00000450305.2       6       632     MSTRG.10        DDX11L1 0.000000        0.000000
8       1       +       12108   26994   MSTRG.10.5      10      5569    MSTRG.10        .       0.057091        0.007904
9       1       +       12804   199997  MSTRG.10.6      12      3567    MSTRG.10        .       0.000000        0.000000
10      1       +       13010   31097   MSTRG.10.7      12      4375    MSTRG.10        .       0.000000        0.000000
11      1       -       13068   26832   MSTRG.11.3      9       5457    MSTRG.11        .       0.995280        0.137788

t_data.ctab모든 파일에서 t_name병치를 추출 FPKM하고 새 파일을 만들고 싶습니다. 새 파일에서 FPKM열은 샘플 이름이어야 합니다. 다음과 같아야 합니다.

t_name         TCGA-A2-A0T3-01A TCGA-A7-A4SA-01A    TCGA-A7-A6VW-01A
MSTRG.1.1              0            0.028181                 0
MSTRG.10.1         0.284182         0.002072             0.046302
MSTRG.11.1         0.077194         0.685535             0.105849
ENST00000456328.2      0            0.307315             0.038961
MSTRG.10.3             0            0.446015             0.009946
MSTRG.11.2         0.051214         0.053577             0.036081
ENST00000450305.2      0            0.110438             0.040319
MSTRG.10.5         0.007904             0                1.430825
MSTRG.10.6             0                0                0.221105
MSTRG.10.7             0            0.199354                 0
MSTRG.11.3         0.137788         0.004792                 0

파일이 2~3개인 경우 cut각 파일에 -f6,12를 사용하여 결합할 수 있습니다. 하지만 지금은 약 1000개의 파일이 있습니다.

답변1

다음의 간단한 방법을 시도해 보세요.

먼저 다음을 수행하십시오.

awk 'FNR==1 { print substr(FILENAME,1,16) >substr(FILENAME,1,16)".tmp" }
     FNR >1 { print $12 > substr(FILENAME,1,16)".tmp" }
     NR==FNR{ print $6  >"first_column.tmp" }' TCGA-A*/t_data.ctab

그런 다음 paste쉼표로 구분된 파일과 함께 보관하세요( -d,사용하려면 탭을 제거하세요).

paste -d, *.tmp
t_name,TCGA-A2-A0T3-01A,TCGA-A7-A4SA-01A,TCGA-A7-A6VW-01A
MSTRG.1.1,0.000000,0.00000,0.0000
MSTRG.10.1,0.284182,0.28418,0.2841
MSTRG.11.1,0.077194,0.07719,0.0771
ENST00000456328.2,0.000000,0.00000,0.0000
MSTRG.10.3,0.000000,0.00000,0.0000
MSTRG.11.2,0.051214,0.05121,0.0512
ENST00000450305.2,0.000000,0.00000,0.0000
MSTRG.10.5,0.007904,0.00790,0.0079
MSTRG.10.6,0.000000,0.00000,0.0000
MSTRG.10.7,0.000000,0.00000,0.0000
MSTRG.11.3,0.137788,0.13778,0.1377

답변2

csv 출력에 만족하시나요?

find ballgown -name t_data.ctab | awk ' {
  F=$0
  print F " started"
  split(F,P,"/")
  FN= P[2]
  TF[FN]=1
  getline < F
  while ((getline < F) > 0) {
    TN[$6]=1
    TV[FN ":" $6] = $NF
  }
  close(F)
  print f " done"
}
END {
  printf("tname")
  for (F in TF) {
    printf(", %s",F)
  }
  print ""
  for (N in TN) {
    printf("%s",N)
    for (F in TF) {
      printf(", %s",TV[F ":" N])
    }
    print ""
  }
}
'

답변3

질문 댓글에서 언급한 대로 질문을 두 가지 작업으로 나누었습니다. 이는 각 파일의 첫 번째 열이 정확히 동일하고 각 파일의 행 수가 동일하기 때문에 가능합니다.

무도회 드레스 카탈로그에 자신을 배치하십시오:

cd ballgown

첫 번째 단계에서는 첫 번째 열을 포함하는 출력 파일을 만듭니다.

cut -f6 TCGA-A7-A6VW-01A/t_data.ctab > out.tab

대부분의 작업은 find다음과 같은 조합을 통해 수행 됩니다 perl.

find -iname t_data.ctab -exec perl -i.bak -lane 'if($.==1){$ARGV=~/([-\w]+)\/.*$/;$f=$1} if(1..eof&&($n=$.)){$a[$.]=$F[11];$a[1]=$f;next}; print "$_\t$a[$.-$n]"' {} out.tab \;

노트:이는 파괴적인 동작입니다. 원본 파일은 보존되고 .bak확장자는 추가됩니다.


비파괴 버전, 활용됨 sponge( findloop로 대체됨 for):

for F in */t_data.ctab; do perl -lane 'if(1..eof&&($n=$.)){$a[$.]=$F[11];$a[1]=$ARGV=~s/([-\w]+)\/.*$/$1/r;next} print "$_\t$a[$.-$n]"' $F out.tab | sponge out.tab; done;

답변4

완전히 프로그래밍 가능한 솔루션PHP.

<?php
$filenames = glob('*/t_data.ctab');
foreach($filenames as $k=>$filename) {
    $name = pathinfo($filename)['dirname'] . "\n";
    $file = file($filename);
    foreach ($file as $n => $line) {
        $line = explode("\t", $line);
        if ($n === 0) {
            $line[11] = $name;
        }
        if ($k === 0) {
            $out[$n] = $line[5] . "\t" . $line[11];
        } else {
            $out[$n] = trim($out[$n]) . "\t" . $line[11];
        }
    }
}
file_put_contents('out.tab', $out);

용법:

  • ballgown디렉토리 에 자신을 배치
  • 파일을 저장하고 이름을 지정하십시오.script.php
  • 스크립트 실행php script.php
  • out.tab파일에서 출력을 찾을 수 있습니다.

노트:

PHP 설치 및 사용 방법, 스크립트의 기능, 특정 요구 사항에 맞게 조정하는 방법에 대한 추가 지침이 필요한 경우 알려주십시오.


이것은 동일한 솔루션입니다.파이썬, 댓글에 언어가 언급되었기 때문입니다. Python을 처음 작성해 보는데 개선 사항을 제안해 주세요.

import os, glob
out = []
for k, filename in enumerate(glob.glob('*/t_data.ctab')):
    with open(filename, 'r') as f:
        file = f.readlines()
        for n, line in enumerate(file):
            line = line.split("\t")
            if n == 0:
                line[11] = os.path.dirname(filename) + "\n"
            if k == 0:
                out.append(line[5] + "\t" + line[11])
            else:
                out[n] = out[n].strip() + "\t" + line[11]
outfile = open('out.tab', 'w')
outfile.write("".join(out))

동일한 방법이 다음과 같이 작성됩니다.진주하나의 선:

perl -lane '$a[$n].=($a[$n]?"":$F[5])."\t".($n<1?$ARGV=~s#([-\w]+)\/.*$#$1#r:$F[11]); $n=eof?0:$n+1}{print "$_" for @a' */t_data.ctab

관련 정보