我有一个包含多个列的文件,并已识别出第 3 列中的值已重复的行。
输入示例:
A B C
1 2 APPLE
3 4 PEAR
9 3 LEMON
8 3 ORANGE
8 2 APPLE
3 4 APPLE
9 3 LEMON
8 3 PEAR
我可以使用以下方法计算第 3 列中的单词被重复的频率:
awk '{print $3}' [input filename] | sort | uniq -c > [output filename]
输出:
3 APPLE
2 PEAR
2 LEMON
1 ORANGE
我想做的是保留重复 3 次的行:
期望的输出:
APPLE
或者
1 2 APPLE
8 2 APPLE
3 4 APPLE
我不介意所有列是从原始输入文件打印还是仅打印第三列值。
使用sort -u
打印出至少出现过一次的任何行,这不是我想要的。
答案1
另一种方法是检查文件两次,第一次构建参考,第二次根据需要进行过滤
$ awk 'NR==FNR{a[$3]++; next} a[$3]==3' ip.txt ip.txt
1 2 APPLE
8 2 APPLE
3 4 APPLE
$ awk 'NR==FNR{a[$3]++; next} a[$3]==2' ip.txt ip.txt
3 4 PEAR
9 3 LEMON
9 3 LEMON
8 3 PEAR
$ awk 'NR==FNR{a[$3]++; next} a[$3]<2' ip.txt ip.txt
A B C
8 3 ORANGE
答案2
awk解决方案:
-- 仅输出发生的条目至少3次:
awk '++a[$3]==3{ print $3 }' file
++a[$3]
- 第三个字段的唯一值的数量连续增加
-- 仅输出发生的条目确切地3次:
awk '{++a[$3]}END{ for(i in a) if(a[i]==3) print i }' file
输出:
APPLE
答案3
将管道的输出传递出去awk '$1 == 3 { print $2 }'
以获得APPLE
.
awk
或者,从头开始计数:
awk '{ c[$3]++; r[$3] = r[$3] ? r[$3] ORS $0 : $0 } END { for (i in c) { if (c[i] == 3) print r[i] } }' file
1 2 APPLE
8 2 APPLE
3 4 APPLE
该awk
脚本将在 中计算c
第 3 列中的值出现的次数。每个输入行都附加r
一个关联数组,例如c
,在第三列上键入。
最后,仅输出第三列恰好出现三次的行。
答案4
好吧,也许不是最优雅的方式,但下面的方法是有效的。它通过将每一行解析为来扩展您已经完成的操作过滤掉那些出现次数不严格大于 2 的内容。
awk '{print $3}' yourInputFile | sort | uniq -c | while read -r line
do
echo $line | [ `awk '{print $1}'` -gt 2 ] && echo $line | awk '{print $2}'
done
如果您希望将显示限制为出现次数严格等于 3 的行,就更简单了。 Agrep
可以按照评论中的建议使用@wvxvw
。在这种情况下,您甚至不需要迭代,但您必须屏蔽grep
不获取以 3 开头但更大的值,例如 30:
awk '{print $3}' yourInputFile | sort | uniq -c | grep '^\s*3\s' | awk '{print $2}'
在这两种情况下,输出都是:
APPLE