如何 grep 查找多行上的多个模式?

如何 grep 查找多行上的多个模式?

准确地说

Some text
begin
Some text goes here.
end
Some more text

我想提取从“开始”到“结束”的整个块

使用 awk 我们可以这样做

awk '/begin/,/end/' text

怎么办grep?某些 *nix 上是否有grep可以完成此操作的实现?

答案1

grep,这g/re/p是一个基本工具p打印与 a 匹配的行r规则的e表达。

你想要更多这里像s特雷姆编辑伊托:

sed '/^begin$/,/^end$/!d'

或者更通用的文本处理工具,具有高级语言,例如awkperl...正如您已经发现的那样。

话虽如此,有些grep实现还可以走得更远一些。

pcregrep -M '(?s)^begin$.*?^end$'

那是使用多线模式 (-M);(?s)切换sPCRE 正则表达式中的标志,以便.也匹配换行符。

对于当前版本的,如果和的间隔超过 20kiB(或指定的缓冲区大小),pcregrep则不能保证其正常工作。beginend

例如,它将匹配

(seq 12091; echo begin; seq 4315; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'

但不在:

(seq 12091; echo begin; seq 4316; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'

或者使用grep带有 PCRE 支持的 GNU 构建并假设文件不包含 NUL 字符:

grep -zoP  '(?ms)^begin$.*?^end$'

然而,这意味着grep将在开始搜索之前将整个文件加载到内存中,因此除小文件外不应使用。它还会在输出中附加一个 NUL 字符。

无论如何,grep不是去这里的正确方法。

相关内容