views:

2477

answers:

5

I needed to find all the files that contained a specific string pattern. The first solution that comes to mind is using find piped with xargs grep:

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

But if I need to find patterns that spans on more than one line, I'm stuck because vanilla grep can't find multiline patterns.

+5  A: 

So I discovered pcregrep which stands for Perl Compatible Regular Expressions GREP.

For example, you need to find files where the '*name' variable is immediatelly followed by the '*description' variable:

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

Tip: you need to include the line break character in your pattern. Depending on your platform, it could be '\n', \r', '\r\n', ...

Oli
+4  A: 

Is there any particular reason why

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

won't achieve the same result?

ayaz
works with GNU grep on win32
+1  A: 

On my system (ubuntu):

grep: The -P option is not supported

On another system (Debian):

grep: Support for the -P option is not compiled into this --disable-perl-regexp binary

I suppose that for some reasons they disabled this option in debian based distribution.

Oli
I did not know that. I am not sure why Debian-based systems do not ship grep with -P support. I am on Slackware, and the grep on it supports it.
ayaz
A: 

Here is a more useful example:

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

It searches the title tag in a html file even if it spans on multiple lines.

Oli
A: 

Why dont you go for awk

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

Amit