AWK实现:当第1列与第2列匹配时删除所有相关行
如何删除重复行及首次出现的基准行?
你想要的是完全移除所有存在重复的组——也就是只要某一行的前两列组合出现超过一次,不管是首次出现的基准行还是后续的重复行,都全部删掉,只保留那些前两列组合唯一的行。
你的现有代码awk '!a[$1$2]++'的作用正好相反:它会保留每个前两列组合的首次出现行,去掉后续重复行,不符合你的需求。
解决方案:用两次遍历的awk命令
可以通过两次读取输入文件来实现:第一次统计每个前两列组合的出现次数,第二次只输出出现次数为1的行,这样既能完美保留原输入顺序,又能满足需求:
awk 'NR==FNR {cnt[$1$2]++; next} cnt[$1$2]==1' input.txt input.txt
代码逻辑解释
NR==FNR:这是awk里判断是否在处理第一个文件的常用写法(NR是全局记录数,FNR是当前文件的记录数,只有处理第一个文件时两者相等)。第一次遍历中,我们用cnt[$1$2]++统计每个前两列组合的出现次数。next:跳过后续操作,直接处理下一行,确保第一次遍历只完成统计工作。- 第二次遍历文件时,我们检查当前行的前两列组合对应的
cnt值是否为1,如果是就输出该行——这意味着这个组合只出现过一次,没有任何重复。
测试示例
输入:
HNSONV LSVRNV 10 srlg-value 52000 HNSONV PHNAAZ 0 srlg-value 53000 HRHNLA PNSCFL 0 srlg-value 54000 HRHNLA PNSCFL 10 srlg-value 55000 HRHNLA PNSCFL 20 srlg-value 54500 HRHNLA PNSCFL 30 srlg-value 55500 JHSNAR KSCYMO 0 srlg-value 56000 JHSNAR OKCYOK 0 srlg-value 57000
输出:
HNSONV LSVRNV 10 srlg-value 52000 HNSONV PHNAAZ 0 srlg-value 53000 JHSNAR KSCYMO 0 srlg-value 56000 JHSNAR OKCYOK 0 srlg-value 57000
这个结果完全符合你的期望:所有前两列重复的行(包括首次出现的基准行)都被移除,只留下了唯一的行。
如果你的输入来自标准输入(比如管道),可以用临时文件或者/dev/stdin来实现两次读取,不过在大多数场景下,直接指定两次输入文件是最方便的做法。
内容的提问来源于stack exchange,提问作者user3746195
相关产品推荐
相关产品推荐

