How to find patterns across multiple lines using grep?


Grep is not sufficient for this operation.

pcregrep which is found in most of the modern Linux systems can be used as

pcregrep -M  'abc.*(\n|.)*efg' test.txt

where -M, --multiline allow patterns to match more than one line

There is a newer pcre2grep also. Both are provided by the PCRE project.

pcre2grep is available for Mac OS X via Mac Ports as part of port pcre2:

% sudo port install pcre2 

and via Homebrew as:

% brew install pcre

or for pcre2

% brew install pcre2

pcre2grep is also available on Linux (Ubuntu 18.04+)

$ sudo apt install pcre2-utils # PCRE2
$ sudo apt install pcregrep    # Older PCRE

I'm not sure if it is possible with grep, but sed makes it very easy:

sed -e '/abc/,/efg/!d' [file-with-content]

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>


  • -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.

  • -l list matching filenames only.

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