Karl Berry sent me this doc addition (thanks!). I've just pushed his change:
>From 28ec5d35539fd63d8914517e59de8c6f5082dab9 Mon Sep 17 00:00:00 2001 From: Karl Berry <[email protected]> Date: Sat, 29 May 2010 10:29:59 +0200 Subject: [PATCH] doc: discuss matches that span two or more lines * doc/grep.texi (Usage): Discuss matching across lines. (Character Classes and Bracket Expressions) <[:space:]>: refer to it. --- doc/grep.texi | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletions(-) diff --git a/doc/grep.texi b/doc/grep.texi index 87480de..9ee4bc4 100644 --- a/doc/grep.texi +++ b/doc/grep.texi @@ -1246,6 +1246,7 @@ Punctuation characters: @cindex whitespace characters Space characters: tab, newline, vertical tab, form feed, carriage return, and space. +...@xref{usage}, for more discussion of matching newlines. @item [:upper:] @opindex upper @r{character class} @@ -1620,7 +1621,35 @@ This gives no output, because the first alternate @samp{(a)\1} does not match, as there is no @samp{aa} in the input, so the @samp{\1} in the second alternate has nothing to refer back to, meaning it will never match anything. (The second alternate in this example can only match -if the first alternate has matched -- making the second one superfluous.) +if the first alternate has matched---making the second one superfluous.) + +...@item +How can I match across lines? + +Standard grep cannot do this, as it is fundamentally line-based. +Therefore, merely using the @code{[:space:]} character class does not +match newlines in the way you might expect. However, if your grep is +compiled with Perl patterns enabled, the Perl @samp{s} +modifier (which makes @code{.} match newlines) can be used: + +...@example +printf 'foo\nbar\n' | grep -P '(?s)foo.*?bar' +...@end example + +With the GNU @command{grep} option @code{-z} (@pxref{File and +Directory Selection}), the input is terminated by null bytes. Thus, +you can match newlines in the input, but the output will be the whole +file, so this is really only useful to determine if the pattern is +present: + +...@example +printf 'foo\nbar\n' | grep -z -q 'foo[[:space:]]\+bar' +...@end example + +Failing either of those options, you need to transform the input +before giving it to @command{grep}, or turn to @command{awk}, +...@command{sed}, @command{perl}, or many other utilities that are +designed to operate across lines. @item What do @command{grep}, @command{fgrep}, and @command{egrep} stand for? -- 1.7.1.348.gb26ba
