如何 grep 查找重复模式的重复模式?

如何 grep 查找重复模式的重复模式?

我有一个文本文件 Fred.txt:

% cat -e fred.txt 
00:$
00:04:$
01:00:23:34$
01:$
01:40:$
01:40:32:$
%

我可以 grep 查找包含 2 位数字和冒号的行:

% pcregrep -e '[\d]{2}:' fred.txt   
00:
00:04:
01:00:23:34
01:
01:40:
01:40:32:
%

但是当我尝试获取该模式的重复模式时,它找不到它们:

% pcregrep -e '[[\d]{2}:]{2}' fred.txt
%

我希望获得与此相同的输出:

% pcregrep -e '[\d]{2}:[\d]{2}:' fred.txt
00:04:
01:00:23:34
01:40:
01:40:32:
%

最终,我将在更大的文件中寻找更多嵌套的重复模式,因此我不想每次重复模式时都进行定义。如何 grep 查找重复该模式的行?

答案1

使用GNUgrep

$ grep -Eo '([0-9]{2}:){2,}' fred.txt 
00:04:
01:00:23:
01:40:
01:40:32:

答案2

[xyz]所谓括号表达式就是匹配集合内的字符。这里,xyz

[\d]在 POSIX 基本正则表达式中将匹配 或\d但在与 perl 兼容的正则表达式中,它与单独匹配相同\d:数字。例如,这允许[\da-fA-F]匹配一个十六进制数字,但在这种[\d]情况下,这是没有意义的,因为您最好使用\d.

无论如何,它不适用于\(...\)POSIX 基本正则表达式或(...)POSIX 扩展正则表达式或 PCRE 中所需的分组。

PCRE 还有其他一些分组变体,例如(?:...)哪些组不创建反向引用,(?|...)哪些组但影响反向引用的交替编号方式,或(?>...)分组运算符的所有格变体等。

在这里,您不需要反向引用,因此您不妨使用(?:...)

pcregrep '(?:\d{2}:){2}'

将匹配以下行包含2 个(2 位数字后跟一个:)。如果您想匹配以下行实际上x,您需要添加该-x选项。

这里,

pcregrep '(?:\d\d:){2}'

实际上会更短。

pcregrep '(\d\d:){2}'

会产生相同的效果,但效率可能会稍低,因为我们没有告诉pcregrep不要打扰捕获里面有什么(...)

请参阅man pcrepattern参考资料 了解有关 PCRE 语法的更多信息。

答案3

使用grep

$ grep -Eo '([^:]*:[[:digit:]]+:?)+' input_file
00:04:
01:00:23:34
01:40:
01:40:32:

相关内容