如何在文件中搜索多行模式?

时间:2008-09-30 11:54:18

标签: linux command-line grep find pcregrep

我需要找到包含特定字符串模式的所有文件。想到的第一个解决方案是使用找到管道,使用 xargs grep

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

但是如果我需要找到跨越多行的模式,我就会被卡住,因为vanilla grep无法找到多行模式。

11 个答案:

答案 0 :(得分:92)

所以我发现pcregrep代表 Perl兼容正则表达式GREP

例如,您需要查找“ _name ”变量后面紧跟“ _description ”变量的文件:

find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'

提示:您需要在模式中包含换行符。根据您的平台,它可以是'\ n',\ r','\ r \ n',...

答案 1 :(得分:84)

为什么不选择awk

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

答案 2 :(得分:67)

以下是使用GNU grep的示例:

grep -Pzo '_name.*\n.*_description'
  

-z / --null-data将输入和输出数据视为行序列。

另见here

答案 3 :(得分:20)

grep -P也使用libpcre,但很多安装得更广泛。要查找html文档的完整title部分,即使它跨越多行,您也可以使用:

grep -P '(?s)<title>.*</title>' example.html

由于the PCRE project实现了perl标准,请使用perl文档作为参考:

答案 4 :(得分:15)

这是一个更有用的例子:

pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html

它会搜索html文件中的标题标记,即使它最多可以分为5行。

以下是无限行的示例:

pcregrep -Mi "(?s)<title>.*</title>" example.html 

答案 5 :(得分:7)

使用silver searcher

ag 'abc.*(\n|.)*efg'

银色搜索者的速度优化可能会在这里发挥作用。

答案 6 :(得分:4)

您可以在此处使用grep替代sift(免责声明:我是作者)。

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

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

(搜索指定多行正则表达式模式的所有* .py文件)

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

答案 7 :(得分:3)

这个答案可能有用:

Regex (grep) for multi-line search needed

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

Use grep --exclude/--include syntax to not grep through certain files

答案 8 :(得分:2)

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

答案 9 :(得分:1)

使用ex / vi编辑器和globstar option(语法类似于awksed):

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

其中aaa是您的起点,bbb是您的结束文字。

要递归搜索,请尝试:

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

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

答案 10 :(得分:0)

@Marcin: awk示例非贪婪:

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