How to find patterns across multiple lines using grep?

Here is a solution inspired by this answer:

  • if ‘abc’ and ‘efg’ can be on the same line:

      grep -zl 'abc.*efg' <your list of files>
    
  • if ‘abc’ and ‘efg’ must be on different lines:

      grep -Pzl '(?s)abc.*\n.*efg' <your list of files>
    

Params:

  • -P Use perl compatible regular expressions (PCRE).

  • -z Treat the input as a set of lines, each terminated by a zero byte instead of a newline. i.e. grep treats the input as a one big line. Note that if you don’t use -l it will display matches followed by a NUL char, see comments.

  • -l list matching filenames only.

  • (?s) activate PCRE_DOTALL, which means that ‘.’ finds any character or newline.

Leave a Comment