使用AWK比对两文件列并输出匹配行:匹配行缺失问题排查
问题诊断与解决方案
看起来你遇到的问题核心出在文件格式匹配和awk逻辑对输入的解析上,咱们一步步拆解:
为什么你的命令只返回AARS行?
先看你提供的测试file1代码块:
AAGAB AAK1 AAMDC AAMP AAR2 AARD AARS
这是单行空格分隔的所有基因,但你的awk命令NR==FNR{c[$1]++;next}是默认file1的每行仅包含一个基因(即第1列是单个基因)。所以awk处理file1时,只会把第一列的AAGAB存入数组c,后面的AAK1、AAMDC等都被当成同一行的第2、3...列,完全没被加入匹配数组。
至于你能得到AARS行,大概率是测试时的输入误差(比如实际file1最后一行单独写了AARS),但整体逻辑没覆盖到所有基因。
针对你的需求的正确命令
根据你描述的真实场景(file1是1列约14000行,file2是6列约40000行),分两种情况给出解决方案:
情况1:file1确实是每行1个基因(符合你描述的1列格式)
如果file1每行仅一个基因(不管是空格还是制表符分隔),用下面的命令即可,awk会自动识别任意空白作为分隔符:
awk 'NR==FNR{c[$1]++;next}c[$5]' file1 file2
如果你的文件严格用制表符分隔,也可以明确指定分隔符:
awk -F '\t' 'NR==FNR{c[$1]++;next}c[$5]' file1 file2
情况2:file1是单行/多行空格分隔的多个基因(比如你测试代码块的格式)
如果file1是把多个基因放在同一行(或每行多个),需要遍历所有字段存入匹配数组:
awk 'NR==FNR{for(i=1;i<=NF;i++)c[$i]++;next}c[$5]' file1 file2
验证你的测试文件
先修正测试文件的正确格式,才能得到你期望的输出:
正确的file1(每行1个基因):
AAGAB AAK1 AAMDC AAMP AAR2 AARD AARS
正确的file2(每行6列,制表符分隔):
chr14 94463615 94473898 NR_024182 AAGAB + chr10 74033676 74035797 NM_019058 AAK1 + chr22 38035683 38052050 NM_018957 AAMDC + chrX 47001614 47004609 NM_019056 AAMP - chr9 21994789 22077889 NR_047539 AAR2 + chr16 20370491 20416033 NM_174924 AARD - chr1 210111518 210337633 NM_001146262 AARS + chrX 30233674 30238206 NM_002364 MAGEB2 + chrX 30261847 30270155 NM_002363 MAGEB1 +
用情况1的命令运行,就能得到你期望的所有匹配行。
额外验证技巧
如果不确定数组里有没有存入所有基因,可以先打印file1的解析结果:
awk 'NR==FNR{c[$1]++;print $1, c[$1];next}' file1
如果输出只有1条结果,说明file1的格式不是每行一个基因,或者分隔符设置错误。
内容的提问来源于stack exchange,提问作者cutts
相关产品推荐
相关产品推荐

