AWK按CSV第一列匹配全量拼接行(保留重复匹配)实现问题
问题原因
原有代码存在两处逻辑缺陷导致同键仅能匹配一次:
- 存储file1记录时直接用第一列作为数组索引,同键的后续行直接覆盖前面的行,同键仅保留最后一条记录
- 匹配到一次同键结果后直接执行
delete file1[key]删除键,后续同键的记录无法再匹配,未匹配的同键行还会被误判定为仅file1独有
修改后代码
BEGIN { FS=OFS="," } FNR==1 { next } { key = $1 } # 读取第一个文件(file1),同键多条全部存储 NR==FNR { cnt[key]++ file1[key, cnt[key]] = $0 next } # 读取第二个文件(file2) key in cnt { # 遍历当前key对应的所有file1行,全部拼接输出 for(i=1; i<=cnt[key]; i++) { print file1[key, i], $0 > "./out_combined.csv" } # 标记该key已匹配,避免后续输出到file1独有文件 matched[key] = 1 next } # 未匹配到的file2行输出到独有文件 { print > "./out_file2_only.csv" } END { # 遍历所有file1的key,未匹配的输出到独有文件 for (key in cnt) { if (!(key in matched)) { for(i=1; i<=cnt[key]; i++) { print file1[key, i] > "./out_file1_only.csv" } } } }
核心修改说明
- 新增
cnt[key]变量计数同键的行数,用file1[key, 序号]二维数组存储同键的所有行,解决同键覆盖问题 - 匹配到同键时不再删除键,而是遍历该键对应的所有file1行全部拼接输出,支持一对多、多对多的全匹配
- 新增
matched[key]标记已匹配的键,避免已匹配的键对应的行被误输出到file1独有文件
按照你给出的示例输入,修改后的代码会输出2条fishing相关的拼接结果,且fishing不会出现在两个独有文件中,符合需求。
内容的提问来源于stack exchange,提问作者Waldonutz
相关产品推荐
相关产品推荐

