如何用Awk匹配两文件双列并输出匹配及不匹配结果行
多列文件匹配合并实现方案
需求说明
- 两个3列的大型文件,需按第1、2列的组合精准匹配
- 匹配成功:将文件2的第3列追加到文件1对应行的第3列后
- 额外输出:文件2中未匹配文件1的行,以及文件1中未匹配文件2的行
示例文件与期望输出
File 1
THR190 GLU195 50.6 VAL188 ASP197 99.2 PHE199 LYS184 2.5 .......
File 2
THR190 GLU195 0.6 PHE199 LYS184 100.0 ARG196 VAL188 22.5 .......
期望输出
THR190 GLU195 50.6 0.6 VAL188 ASP197 99.2 PHE199 LYS184 2.5 100.0 ARG196 VAL188 22.5 .......
现有问题代码
你当前的代码仅用第1列作为匹配键,无法满足第1+2列的组合匹配需求:
awk 'FNR==NR{lines[$1]=$2;next}{print $0,lines[$1]}'
修正后的Awk代码
以下代码实现完整需求,核心是用第1列+第2列的组合作为唯一匹配键:
awk ' # 读取文件1,存储第1+2列的键与对应的第3列 FNR==NR { key = $1 " " $2 file1[key] = $3 next } # 处理文件2 { key = $1 " " $2 if (key in file1) { # 匹配成功,按格式输出文件1内容+文件2第3列 printf "%s %s %s %s\n", $1, $2, file1[key], $3 matched[key] = 1 } else { # 暂存文件2中未匹配的行 unmatched[++cnt] = $0 } } # 处理完所有行后,输出文件1中未匹配的行和文件2未匹配的行 END { # 输出文件1未匹配行 for (key in file1) { if (!(key in matched)) { printf "%s %s \n", key, file1[key] } } # 输出文件2未匹配行 for (i=1; i<=cnt; i++) { split(unmatched[i], arr) printf "%s %s %s\n", arr[1], arr[2], arr[3] } } ' file1.txt file2.txt
代码关键点
- 联合匹配键:用
$1 " " $2作为数组索引,确保只有第1、2列完全一致才会匹配 - 标记匹配状态:用
matched数组记录已匹配的键,避免重复输出 - 格式控制:用
printf精准控制输出格式,保证列对齐(可根据实际需求调整空格数) - 未匹配行处理:分别暂存和输出文件1、文件2中未匹配的行
内容的提问来源于stack exchange,提问作者EA00
相关产品推荐
相关产品推荐

