模式按行名称匹配多个文件中的多个列

时间:2017-11-17 18:12:16

标签: bash unix join awk

我有两个文件,一个包含基因名称的完整列表,另外三个包含基因名称的部分列表。我想将这些文件全部匹配到一个。所有部分文件都是不同的行数,但 3000列,都代表不同的单元格。我一直在尝试完全加入这些文件,但是当我使用awk时,只保留了一列。

mergedAll.txt

GENE
SOX2
BRCA1
BRCA2
RHO

ultimatecontrolMed.txt

GENE     CELL1   CELL2   CELL3
SOX2     30      152     2000
BRCA2    400     234     73
RHO      12      2       0

我想要的输出是

GENE     CELL1   CELL2   CELL3
SOX2     30      152     2000
BRCA1    0       0       0
BRCA2    400     234     73
RHO      12      2       0

我跑:

awk 'NR==FNR{k[$1];next}{b[$1]=$0;k[$1]}
END{for(x in k)
      if ( x== "GENE" )
         printf"%s %s\n",x,b[x]
      else
         printf"%s  %d\n",x,b[x]
}' mergedAll.txt ultimatecontrolMed.txt > test.txt

我得到了:

GENE CELL1 CELL 2 CELL3
SOX2 2000
BRCA1 0
BRCA2 73
RHO 0

由于某种原因,它将保留最后一列计数但不保留任何其他行,并保留所有单元格名称。我对awk没有任何经验,所以这对我来说是一个很大的挑战,如果有人能提供更好的解决方案,我会很高兴。

4 个答案:

答案 0 :(得分:1)

awk救援!

$ awk 'NR==FNR {a[$1]=$0; next} 
               {print (a[$1]?a[$1]:($1 FS 0 FS 0 FS 0))}' file2 file1 | 
  column -t

GENE   CELL1  CELL2  CELL3
SOX2   30     152    2000
BRCA1  0      0      0
BRCA2  400    234    73
RHO    12     2      0

column的最终管道用于漂亮打印。请注意文件的顺序。

不要硬编码您可以尝试此替代方案的列数

$ awk 'NR==1   {for(i=2;i<=NF;i++) missing=missing FS 0}  
       NR==FNR {a[$1]=$0; next} 
               {print (a[$1]?a[$1]:($1 missing))}' file2 file1

答案 1 :(得分:0)

您能否请关注awk并告诉我这是否对您有所帮助。

awk 'FNR==NR{a[$0];next} ($1 in a){print;delete a[$1];next} END{for(i in a){print i,"0 0 0"}}' mergedAll.txt  ultimatecontrolMed.txt

答案 2 :(得分:0)

问题是您使用b[x]格式打印%d。这是用于打印单个整数,因此它将忽略b[x]中的所有其他整数。变化

     printf"%s  %d\n",x,b[x]

为:

    if (b[x]) {
        printf "%s\t%s\n", x, b[x]
    } else {
        printf "%s" x;
        for (i = 0; i < 3000; i++) printf "\t0"
        print ""
    }

这样它将打印整个值。如果没有相应的值,它将打印零。

3000替换为适当数量的单元格。如果您不想对其进行硬编码,则可以在NF-1(第二个文件的第一行)时从FNR == 1 && FNR != NR获取它。

答案 3 :(得分:0)

join -a 1 -a 2 -e 0 -o 0 2.{2..4}  mergedAll.txt ultimatecontrolMed.txt

2.{2..4}打印输出字段列表,可以轻松适应任意数量的字段。

当你提到三个输入文件时,可以将第一个连接的结果输入到第二个连接中

join .... file1 file2 | join ... file3 

join需要排序输入。这可能是解决方案的一个杀手锏。