从多个文件中剪切特定列并使用unix工具重新整形

时间:2011-03-18 19:53:34

标签: perl bash unix sed awk

我在一个文件夹中有几百个文件。这些文件中的每一个都是制表符分隔的文本文件,其中包含超过一百万行和27列。从每个文件,我希望只能提取特定的列(比如只拉出列:1,2,11,12,13)。专栏3:10& 14:27可以忽略。我希望能够对文件夹中的所有文件(比如2300个文件)执行此操作。每个2300文件中的列看起来像这样..........

Sample.ID      SNP.Name    col3  col10  Sample.Index   Allele1...Forward       Allele2...Forward col14 ....col27      
1234567890_A    rs758676    -     -      1              T                       T                 -     ....col27
1234567890_A    rs3916934   -     -      1              T                       T                 -     ....col27
1234567890_A    rs2711935   -     -      1              T                       C                 -     ....col27
1234567890_A    rs17126880  -     -      1              -                       -                 -     ....col27
1234567890_A    rs12831433  -     -      1              T                       T                 -     ....col27
1234567890_A    rs12797197  -     -      1              T                       C                 -     ....col27

第二个文件中的剪切列可能如下所示....

Sample.ID      SNP.Name    col3  col10  Sample.Index   Allele1...Forward       Allele2...Forward col14 ....col27      
1234567899_C    rs758676    -     -      100            T                       A                 -     ....col27
1234567899_C    rs3916934   -     -      100            T                       T                 -     ....col27
1234567899_C    rs2711935   -     -      100            T                       C                 -     ....col27
1234567899_C    rs17126880  -     -      100            C                       G                 -     ....col27
1234567899_C    rs12831433  -     -      100            T                       T                 -     ....col27
1234567899_C    rs12797197  -     -      100            T                       C                 -     ....col27

第3个文件中的剪切列可能如下所示....

Sample.ID      SNP.Name    col3  col10  Sample.Index   Allele1...Forward       Allele2...Forward col14 ....col27      
1234567999_F    rs758676    -     -      256            A                       A                 -     ....col27
1234567999_F    rs3916934   -     -      256            T                       T                 -     ....col27
1234567999_F    rs2711935   -     -      256            T                       C                 -     ....col27
1234567999_F    rs17126880  -     -      256            C                       G                 -     ....col27
1234567999_F    rs12831433  -     -      256            T                       T                 -     ....col27
1234567999_F    rs12797197  -     -      256            C                       C                 -     ....col27

Sample.IDSample.Index的宽度在每个文件中都相同,但可以在文件之间更改。 Sample.ID的值在每个文件中相同,但文件之间不同。每个剪切文件在“SNP.Name”列下具有相同的值。 Sample.Index列有时可能与不同的文件相同。其他两列值(Allele1...Forward & Allele2...Forward)可能会更改,并在每个SNP.Name下为每个Sample.ID粘贴“”sep。

我最终希望将2300个文件中的所有剪切列合并(tab-delemited)为这种格式......

Sample.Index  Sample.ID     rs758676   rs3916934   rs2711935  rs17126880  rs12831433  rs12797197        
1             1234567890_A  T T         T T         T C         0 0         T T         T C        
200           1234567899_C  T A         T T         T C         C G         T T         T C        
256           1234567999_F  A A         T T         T C         C G         T T         C C        

简单来说,我希望能够根据Sample.ID列将长格式转换为宽格式。这类似于R中的reshape函数。我用R尝试了这个并且它耗尽内存并且非常慢。任何人都可以帮助使用unix工具吗?

当reshape.sh应用于20个文件时......它在输出中产生了一个虚假的“样本行”。这里有前4个字段。

Sample.Index    Sample.ID   rs476542    rs7073746   
1234567891_A          11         C C          A G   
1234567892_A         191         T C          A G   
1234567893_A         204         T C          G G   
1234567894_A          15         T C          A G   
1234567895_A         158         T T          A A   
1234567896_A         208         T C          A A   
1234567897_A         111         T T          G G   
1234567898_A         137         T C          G G   
1234567899_A         216         T C          A G   
1234567900_A         113         T C          G G   
1234567901_A         152         T C          A G   
1234567902_A         178         C C          A A   
1234567903_A         135         C C          A A   
1234567904_A         125         T C          A A   
1234567905_A         194         C C          A A   
1234567906_A         110         C C          G G   
1234567907_A         126         C C          A A   
Sample         -                                    
1234567908_A         169         C C          G G   
1234567909_A         173         C C          G G   
1234567910_A         168         T C          A A   

1 个答案:

答案 0 :(得分:5)

#!/bin/bash

awk '

BEGIN {
  maxInd = length("Sample.Index")
  maxID  = length("Sample.ID")
}

FNR>11 && $2 ~ "^rs" {
  SNP[$2]
  key[$11,$1]
  val[$2,$11,$1]=$12" "$13
  maxInd = (len=length($11)) > maxInd ? len : maxInd
  maxID  = (len=length($1))  > maxID  ? len : maxID
}

END {
  printf("%-*s\t%*s\t", maxInd, "Sample.Index", maxID, "Sample.ID")
  for (rs in SNP)
    printf("%s\t", rs)
  printf("\n")

  for(pair in key) {
    split(pair,a,SUBSEP)
      printf("%-*s\t%*s\t", maxInd, a[1], maxID, a[2])
      for(rs in SNP) {
        ale = val[rs,a[1],a[2]]
        out = ale == "- -" ||  ale == "" ? "0 0" : ale
        printf("%*s\t", length(rs), out)
      }
      printf("\n")
  }
}' DNA*.txt

概念证明

$ ./reshapeDNA
Sample.Index       Sample.ID    rs2711935       rs10829026      rs3924674       rs2635442       rs715350        rs17126880      rs7037313       rs11983370      rs6424572       rs7055953       rs758676        rs7167305       rs12831433      rs2147587       rs12797197      rs3916934       rs11002902
11              1234567890_A          T T              0 0            C C             0 0            0 0               T C            0 0              C C            T G             0 0            C C              0 0              T C            A G              T T            T C              G G
111             1234567892_A          T T              T C            C C             0 0            0 0               C C            T C              C C            T T             0 0            C C              0 0              T T            A A              T T            T T              G G
1               1234567894_A          T T              0 0            T C             C C            A G               C C            0 0              C C            0 0             T C            C C              T T              T T            A G              T T            C C              G G
12              1234567893_A          T T              0 0            C C             T C            A A               T C            0 0              C C            0 0             T T            C C              T G              T C            A G              T T            T C              G G
15              1234567891_A          T T              C C            C C             0 0            0 0               C C            C C              C C            T T             0 0            C C              0 0              T C            A G              T T            T T              G G