我有两个文件,一个包含基因名称的完整列表,另外三个包含基因名称的部分列表。我想将这些文件全部匹配到一个。所有部分文件都是不同的行数,但 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没有任何经验,所以这对我来说是一个很大的挑战,如果有人能提供更好的解决方案,我会很高兴。
答案 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
需要排序输入。这可能是解决方案的一个杀手锏。