如何使用awk对多分隔符文件实现跨文件指定字段匹配筛选
原有命令错误点
- 文件读取顺序颠倒:
NR==FNR逻辑会优先处理命令中传入的第一个文件,正确顺序应该先读参考文件file2,把比对关键词存入数组,再处理待筛选的file1,原命令把file1放在第一个读取位置,逻辑完全错位 - 取值逻辑不符合需求:用
[/|]做分隔符取固定$3的写法无法适配不同行/数量不一致的情况,你需要提取的是每行最右侧第一个/之后、第一个|之前的字段,和列序号无关 - 匹配字段错误:原命令判断
$1 in a完全偏离目标取值,自然无法得到正确结果
正确awk命令
通用兼容版(适配所有awk版本,包括mawk、gawk、nawk)
awk ' NR==FNR { a[$0] next } { origin = $0 # 贪婪匹配删除最后一个/及之前的所有内容 sub(/.*\//, "") # 删除第一个|及之后的所有内容,得到待比对值 sub(/\|.*/, "") # 命中参考值则输出原始行 if ($0 in a) print origin } ' file2 file1 > output
简化版(仅支持gawk,即GNU awk)
awk 'NR==FNR{a[$0];next} match($0,/\/([^/|]+)\|/,m) && m[1] in a' file2 file1 > output
逻辑验证
针对你给出的测试文件,命令提取的待比对值分别为:
AAB/BBC/customer|fed|12931|→customer,命中,输出/customer|fed|982311|→customer,命中,输出(你给出的期望输出中该行ID写为12931属于笔误,命令会保留文件原始内容输出)BXC/DEF/OTTA|fed|92374|→OTTA,未命中,跳过AVD/customer|FST|8736481|→customer,命中,输出FFS/T6TT/BOSTON|money|18922|→BOSTON,未命中,跳过GTS/trust/YYYY|opt|62376|→YYYY,未命中,跳过XXY/IJSH/trust|opt|62376|→trust,命中,输出
完全匹配你的筛选规则。
内容的提问来源于stack exchange,提问作者Nadia Alice
相关产品推荐
相关产品推荐

