如何基于两列组合筛选文件中仅出现一次的行?
搞定!找出suite与case组合唯一的完整行
你思路方向是对的,用数组统计组合出现次数,但问题出在END块里的print $0——到了END阶段,awk已经处理完所有行,$0早就不指向任何原始输入行了,自然打不出正确内容。
给你两种实用的解决办法,按需选:
办法一:两次扫文件(适合小文件,简单直观)
第一次扫文件统计每个suite:xxx case:xxx组合的出现次数,第二次扫的时候输出那些只出现过一次的行:
NR==FNR { arr[$6,$8]++; next } arr[$6,$8]==1 { print $0 }
用的时候直接这么跑:
awk 'NR==FNR{arr[$6,$8]++;next}arr[$6,$8]==1' 你的输入文件.txt 你的输入文件.txt
- 第一次扫描(
NR==FNR是awk判断当前是第一次读文件的常用写法):把每个组合的出现次数存在数组arr里 - 第二次扫描:检查当前行的组合次数是不是1,是就直接打印整行
办法二:一次扫文件(适合大文件,省内存)
如果你的文件特别大,不想读两次,就用两个数组:一个记次数,一个存第一次出现的行内容。遇到重复组合时,直接把之前存的行标记成无效:
{ key = $6 SUBSEP $8 if (arr[key] == 0) { # 第一次见这个组合,把整行存起来 line[key] = $0 arr[key] = 1 } else if (arr[key] == 1) { # 第二次见,说明重复了,删掉之前存的行,标记成已重复 delete line[key] arr[key] = 2 } } END { # 最后把剩下的唯一行都打出来 for (k in line) { print line[k] } }
这个方法只读一次文件,内存占用只和唯一组合的数量有关,比两次扫描高效。
为啥你的原代码不行?
你原代码里END块循环数组的时候,$0已经没有绑定任何输入行的内容了,打印出来的要么是空,要么是最后一行的内容,根本不是对应组合的原始行。必须要么在第二次扫描时实时判断输出,要么在第一次扫描时就把需要的行存起来才行。
内容的提问来源于stack exchange,提问作者Humble Student
相关产品推荐
相关产品推荐

