保持行重复一定次数

保持行重复一定次数

我有一个包含多个列的文件,并已识别出第 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

相关内容