使用awk对管道分隔文件按列组合去重结果异常的问题
用Awk按多列组合去重时结果异常的解决方法
问题场景
我有一个管道分隔的文件,想要用awk工具根据第2列(name)和第3列(org)的组合值删除重复行。文件内容如下:
id|name|org 1|Firstname Lastname|California Institute of Technology 2|Firstname Lastname|California Institute of Technology Department of Applied Physics and Materials Science 3|Firstname Lastname|California Institute of Technology Department of Applied Physics and Materials Science
执行了这条命令:
awk -F ' *| *' '!uniq[$2,$3]++' test.csv >test_out.csv
结果只得到一行:
1|Firstname Lastname|California Institute of Technology
但预期应该保留两行,怎么解决?
问题根源
你设置的分隔符' *| *'出了问题——这个正则表达式会把空格和管道符都当成分隔符,导致第3列的完整内容被拆成了多个片段。比如第2行里的California Institute of Technology Department...,$3实际只取到了California,而不是整个org列的内容。这样一来,三行的$2,$3组合都是Firstname Lastname,California,被当成重复行过滤,自然只留下第一行。
解决办法
方法1:正确设置管道符为分隔符
awk里|是正则元字符,需要转义后作为分隔符,直接运行:
awk -F '\\|' '!uniq[$2,$3]++' test.csv > test_out.csv
或者用方括号包裹避免转义,效果一样:
awk -F '[|]' '!uniq[$2,$3]++' test.csv > test_out.csv
方法2:同时处理字段首尾的空格(按需使用)
如果字段前后可能存在多余空格,想要先清理再去重,可以用:
awk -F ' *\\| *' '{gsub(/^ +| +$/,"",$2); gsub(/^ +| +$/,"",$3)} !uniq[$2,$3]++' test.csv > test_out.csv
这条命令会先去除第2、3列首尾的空格,再根据组合值判断重复。
最终验证
执行正确命令后,test_out.csv的内容会是:
id|name|org 1|Firstname Lastname|California Institute of Technology 2|Firstname Lastname|California Institute of Technology Department of Applied Physics and Materials Science
完全符合预期的两行结果。
内容的提问来源于stack exchange,提问作者JohnJ
相关产品推荐
相关产品推荐

