113

How to give a pattern for new line in grep? New line at beginning, new line at end. Not the regular expression way. Something like \n.

tuxnani
  • 3,444
  • 5
  • 20
  • 33

6 Answers6

106

try pcregrep instead of regular grep:

pcregrep -M "pattern1.*\n.*pattern2" filename

the -M option allows it to match across multiple lines, so you can search for newlines as \n.

nullrevolution
  • 3,737
  • 1
  • 16
  • 19
96

grep patterns are matched against individual lines so there is no way for a pattern to match a newline found in the input.

However you can find empty lines like this:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 
davidg
  • 5,638
  • 2
  • 31
  • 50
arash kordi
  • 2,350
  • 20
  • 22
  • 4
    At least GNU grep has -z option that makes grep break lines by null character. However, it does not seem to support newline or \n in pattern to match newline, see [bug report](https://bugs.launchpad.net/ubuntu/+source/grep/+bug/1641092). – jarno Nov 12 '16 at 12:15
  • 2
    @jarno It supports \n in patterns with the -P flag – rubystallion Mar 09 '18 at 11:01
30

Thanks to @jarno I know about the -z option and I found out that when using GNU grep with the -P option, matching against \n is possible. :)

Example:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

Result:

bar

Example that involves matching everything including newlines:

.* will not match newlines. To match everything including newlines, use1 (.|\n)*:

grep -zoP 'foo\n\K(.|\n)*'<<<$'foo\nbar\nqux'

Result:

bar
qux

1 Seen here: https://stackoverflow.com/a/33418344

Robin A. Meade
  • 1,376
  • 12
  • 15
rubystallion
  • 2,083
  • 15
  • 17
25

You can use this way...

grep -P '^\s$' file
  • -P is used for Perl regular expressions (an extension to POSIX grep).
  • \s match the white space characters; if followed by *, it matches an empty line also.
  • ^ matches the beginning of the line. $ matches the end of the line.
kenorb
  • 137,499
  • 74
  • 643
  • 694
Manikandan Rajendran
  • 1,072
  • 1
  • 8
  • 9
  • 2
    `-P` is a GNU extension. I am fine for using it when the situation calls for it (typically lookahead/lookbehind), but POSIX grep can do this just file with `[[:space:]]`. – jordanm Sep 29 '12 at 21:29
  • 1
    FWIW, Solaris' and BSD's grep manpages (didn't check others) both have a paragraph for `-P`. GNU is quite standard anyway. :) – K3---rnc Jun 24 '13 at 05:09
  • 1
    From manual page: [-P] This option is not supported in FreeBSD. – Marián Černý Dec 04 '14 at 13:31
  • No [-P] for MacOsX either: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color[=when]] [--colour[=when]] [--context[=num]] [--label] [--line-buffered] [--null] [pattern] [file ...] – Niccolò Jan 12 '17 at 10:50
  • @Niccolò You'll want to `brew install grep` to get GNU grep, which is superior in several ways. https://apple.stackexchange.com/questions/193288/how-to-install-and-use-gnu-grep-in-osx – Ethan Herdrick May 11 '18 at 23:21
6

As for the workaround (without using non-portable -P), you can temporary replace a new-line character with the different one and change it back, e.g.:

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

Basically it's looking for exact match _foo_ where _ means \n (so __ = \n\n). You don't have to translate it back by tr '_' '\n', as each pattern would be printed in the new line anyway, so removing _ is enough.

kenorb
  • 137,499
  • 74
  • 643
  • 694
  • pardon my ignorance, but is using process substituion not yet another NON posix compatible, hence non-portable feature? in posix shell I could not do ` – humanityANDpeace Sep 06 '18 at 11:23
4

just found

grep $'\r'

It's using $'\r' for c-style escape in Bash.

in this article

HHHartmann
  • 41
  • 1
  • carriage return `\r` is not a newline `\n`. If your grepping for windows style line ending you need `\r\n` – CervEd Jan 07 '22 at 11:27