使用AWK对比CSV文件指定列输出匹配结果时如何同时输出不匹配行
解决方案
完全可以在单条AWK命令内实现所有需求,不需要多次解析文件,反而单条命令仅需遍历两次文件,比分开执行的IO开销更小,逻辑也更连贯。
优化后命令
awk -F, ' NR==FNR { # 读取file1,同时存储全量行、标记待校验的未匹配条目 a[$1 FS $4] = $0 unmatched1[$1 FS $4] = $0 next } { key = $1 FS $4 if (key in a) { # 匹配到的行直接拼接输出到合并文件,同时清除file1的未匹配标记 print a[key] "," $0 > "combined.csv" delete unmatched1[key] } else { # file2未匹配行直接写入对应文件 print $0 > "file2_unmatched.csv" } } END { # 遍历剩余的file1未匹配条目输出 for (key in unmatched1) { print unmatched1[key] > "file1_unmatched.csv" } }' file1.csv file2.csv
说明
- 修正了你原脚本中
sub可能误替换的问题:原写法如果行内其他位置出现和「第1列+逗号+第4列」完全一致的字符串,会被错误删除,直接拼接两个行内容的方案更稳妥 - 执行后会直接生成三个文件:
combined.csv(匹配拼接结果)、file1_unmatched.csv(file1未匹配行)、file2_unmatched.csv(file2未匹配行),完全符合你的需求 - 这个方案的内存占用仅和file1的行数正相关,只要file1不是百万级以上的超大文件,运行效率远高于分开多次解析的方案
关于是否要拆分命令的问题
这个需求逻辑非常连贯,单条AWK实现完全没有复杂度负担,拆分执行反而需要多次读取文件、存储中间结果,不仅效率更低,还要维护多段脚本,完全没必要拆分。
内容的提问来源于stack exchange,提问作者Waldonutz
相关产品推荐
相关产品推荐

