Grep 匹配模式两次的行

Grep 匹配模式两次的行

通常grep输出与模式匹配的任何行。我希望能够找到多次与该模式匹配的行。例如,如果我的搜索模式是“foo”,那么:

foo bar      # Would not be matched
foo foo bar  # Would be matched
bar foofoo   # Would be matched
foobarfoo    # Would be matched

有没有一种方法可以告诉我grep只查找包含搜索模式的多个匹配项的行?

答案1

grep -E "(foo.*){2}" file

这在文件或输出的每一行上至少匹配 2 次,您可以给出最小匹配次数。

答案2

如果你想匹配所有匹配的行任何字符串两次:

grep '\(.\{1,\}\).*\1'

您可以通过更改来更改长度以匹配1,

seq 10000 | grep '\(.\{2,\}\).*\1'

这使用基本正则表达式(布雷),因此应该适用于任何 POSIX 兼容的grep

如果将正则表达式转换为使用非贪婪正则表达式(并非所有地方都支持),它似乎不会加快匹配速度:

grep -E '(..*?).*?\1'

该图显示了每个 n 个数字的 100 行(~ 行长度)上有和没有非贪婪运行的运行时间(以秒为单位)。

greedy() {
  a=`seq $1`;
  yes $a | head -n 100 | grep '\(.\{1,\}\).*\1' | LC_ALL=C wc;
}
nongreedy() {
  a=`seq $1`;
  yes $a | head -n 100 | grep -E '(..*?).*?\1' | LC_ALL=C wc;
}
export -f greedy
export -f nongreedy
parallel --jl my.log {2} {1}000 {2} ::: {1..100} ::: greedy nongreedy

在此输入图像描述

答案3

grep "foo.*foo" file.txt

这只会返回foo出现两次或多次的行。它不会返回只出现一次的行。

上面的代码在大多数情况下都可以在没有引号的情况下工作,但在其他情况下,目录中存在与 glob 匹配的文件名,例如foo.barfoo,有必要引用正则表达式,这就是为什么我编辑了答案以包含双引号。

相关内容