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

위와 같이 ballgown1000개의 하위 디렉터리가 있습니다. 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

파일이 두 개 또는 세 개인 경우 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,대신 Tab을 사용하려면 제거하세요).

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

질문에 대한 설명에 설명된 대로 문제를 두 가지 작업으로 분할했습니다. 이는 각 파일의 첫 번째 열이 정확히 동일하고 모든 파일의 행 수가 동일하기 때문에 가능합니다.

ballgown 디렉토리에 위치하십시오:

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(또한 루프 find로 대체됨 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

관련 정보