Is it possible to write a grep statement on multiple lines?

The pattern argument is actually a list of patterns, separated by newlines. This is true even for grep -F: you can search for multiple strings. So you can write:

grep 'foo
bar
barz'

But note that the continuation lines must not be indented: any leading space would be part of the pattern. For this reason, you may prefer to pass the pattern list as separate arguments, with -e in front of each pattern. Then you can use \ at the end of a line to split the shell command across lines between the arguments of the grep command. The two syntaxes are equivalent.

grep -e 'foo' \
     -e 'bar' \
     -e 'barz'

Note that neither of those work with current versions of GNU grep when passed the -P option (for PCRE regexps) which in those cases fails with grep: the -P option only supports a single pattern. You can however use pcregrep instead of GNU grep -P and use the x flag to enter multi-line regexps:

pcregrep '(?x)
  foo |
  bar |
  barz'

With (?x), all whitespace characters including SPC and NL are ignored allowing you to indent the code as you wish.


I don't see a need for | there. You could use multiple -e options spread across lines:

grep -e foo \
     -e bar \
     -e barz

using Raku (formerly known as Perl_6)

$ cat foo_bar_barz.txt | raku -ne '.grep(/
| foo
| bar
| barz
/).put;'

#outputs:

1. foo
2. bar
3. barz

One of the major reasons for the Perl6 (now Raku) project was to rewrite the regex engine so that more readable code could be inputted. The Raku defaults include the ability to insert spaces between tokens, to write regexes on multiple lines, and also a revision of the "modifier" system (now called "adverbs"). [As an example of the latter, where you used to tag a "g" onto the end of a regex, now that ":g" appears at the head of the regex so you know what you're trying to match from the get-go].

Above is a Raku solution for the example you posted. Note in Raku the | alternation operator implements the longest-token-matching (LTM) strategy. Also you can feel free to insert a "leading" | alternation operator to help you line up tokens (see above). Raku accepts this as normal.

Below, to give you an idea of what's going on behind the scenes, I capture the three tokens individually using the m// match operator instead of grep(). Captures are accomplished with parentheses, with numbering beginning from $0 :

$ cat foo_bar_barz.txt | raku -ne 'say  m/
| (foo)
| (bar)
| (barz)
/;'

#outputs:

「foo」
 0 => 「foo」
「bar」
 0 => 「bar」
「barz」
 0 => 「barz」
Nil

Note the input file is as below (with a bogus line at the end to keep me honest):

$ cat foo_bar_barz.txt
1. foo
2. bar
3. barz
4. ziggy

https://raku.org/

Tags:

Grep