关于linux:如何在文件中搜索多行模式?

How can I search for a multiline pattern in a file?

我需要找到包含特定字符串模式的所有文件。首先想到的解决方案是使用find piped和xargs grep:

1
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'

但如果我需要找到跨越多行的模式,我会陷入困境,因为普通grep找不到多行模式。


所以我发现了pcregep,它代表与perl兼容的正则表达式grep。

例如,您需要查找文件,其中"_name"变量紧跟着"_description"变量:

1
2
find . -iname '*.py' | xargs pcregrep -M '_name.*
.*_description'

提示:您需要在模式中包含换行符。取决于您的平台,它可能是''、
'、'
'、…


你为什么不去参加awk?

1
awk '/Start pattern/,/End pattern/' filename


下面是使用gnu grep的示例:

1
2
grep -Pzo '_name.*
.*_description'

-z/--null-data Treat input and output data as sequences of lines.

在这里也看到


grep -P也使用libpcre,但安装更为广泛。要查找HTML文档的完整title部分,即使它跨越多行,也可以使用以下方法:

1
grep -P '(?s).*' example.html

由于PCRE项目实现了Perl标准,因此请使用Perl文档作为参考:

  • http://perldoc.perl.org/perlre.html修饰符
  • http://perldoc.perl.org/perlre.html扩展模式


下面是一个更有用的示例:

1
2
pcregrep -Mi"(.*
){0,5}" afile.html

它在HTML文件中搜索标题标记,即使它跨越最多5行。

以下是无限行的示例:

1
pcregrep -Mi"(?s).*" example.html


使用银色搜索器:

1
2
ag 'abc.*(
|.)*efg'

银色搜索引擎的速度优化可能会在这里发光。


您可以在这里使用grep可选筛选(免责声明:我是作者)。

它支持多行匹配,并将搜索限制为开箱即用的特定文件类型:

1
sift -m --files '*.py' 'YOUR_PATTERN'

(搜索指定多行regex模式的所有*.py文件)

它适用于所有主要操作系统。查看示例页面,了解如何使用它从XML文件中提取多行值。


这个答案可能有用:

需要多行搜索的regex(grep)

要递归查找,可以使用标志-r(递归)和--include(glob模式)。见:

使用grep--exclude/--include语法在某些文件中不grep


1
perl -ne 'print if (/begin pattern/../end pattern/)' filename


使用ex/vi编辑器和globstar选项(语法类似于awksed

1
ex +"/string1/,/string3/p" -R -scq! file.txt

其中aaa是你的起点,bbb是你的结束语。

要递归搜索,请尝试:

1
ex +"/aaa/,/bbb/p" -scq! **/*.py

注意:要启用**语法,请运行shopt -s globstar(bash 4或zsh)。


@ Marcin:awk示例非贪婪:

1
awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename