Linux中提取行连续出现3次或以上

Linux中提取行连续出现3次或以上

我在 Linux 中有一张表:

A 0
A 0
A 0
B 0
B 1
B 0
B 1
B 0

我想提取连续出现3次或以上的行。

我的预期输出是:

A 0

实际上,3次或更多只是一个简单的例子。实际情况是我想提取连续出现30次以上的行。

任何想法?

谢谢你!

答案1

uniq -c file | awk '$1 >= 3 { print $2,$3 }'

uniq -c输出每一行以及该行连续出现的次数。对于给定的数据,它将产生

   3 A 0
   1 B 0
   1 B 1
   1 B 0
   1 B 1
   1 B 0

awk如果第一个字段大于或等于 3,脚本将采用此值并输出最后两个字段。

结果将是

A 0

答案2

简单的awk可以使用如下。

awk '{!s[$0]++} END{for (x in s) if (s[x]>2) print x}' infile

这是打印重复次数超过 2 次>2但总共重复的行。您可以设置>29让线条重复 ≥‎30 次。

您可以使用 @Philippos 指出的以下命令,仅打印重复 ≥3 次的连续行。

awk 'p!=$0{n=0} {p=$0;n++} (n==3)'

说明: 将前一行存储在 中p,对 中的行进行计数n,如果一行与前一行不同,则重置计数器。在第 3 次或第 30)出现时打印。


或者甚至用简短的方法也可以实现相同的效果:

awk 'p!=$0{n=0;p=$0} ++n==3'

答案3

sed缺少纯净版!这会做:

sed 'x;G;s/\(.*\)\n\1$/+\1/;/\n/d;h;s/^+\{2\}//;/^+/d' file

2将by替换29为连续 30 行。我想知道是否可以以某种方式进行优化。

工作原理:在保留空间中,保留前一行,并+为每个额外出现的行添加前导。现在,对于每一行,x交换缓冲区,因此当前行位于保留空间中。附加G保留空间,因此在模式空间中我们有旧行和新行,由换行符分隔。现在,如果该行出现在换行符之前和之后,我们就有两行相同的行,并且该s命令将其中一行和换行符替换为+.如果模式中仍然有换行符,则行不同,我们可以开始新的循环 ( /\n/d)。否则将修改后的行复制到保留空间以收集+.最后删除+所需的行数(减去一行)。如果仍然存在前导+,则我们收集的行太多或不足,因此d进行删除。

答案4

与单awk脚本:

awk '{k=$1 FS $2}!a[k] || (NR==n && k==pk){ a[k]++; pk=k; n=NR+1 }
     END{ for(i in a) if(a[i] >=3) print i }' file

  • k=$1 FS $2- 关键键,第一和第二字段的串联

  • !a[k] || (NR==n && k==pk)- 检查记录是否第一次出现或与前一条记录同时发生


输出:

A 0

相关内容