85

I have a text file named compare.txt where I want to extract the single line that follows every line that contains the pattern nmse_gain_constant. The following command gets me close:

grep -A 1 nmse_gain_constant compare.txt | grep -v nmse_gain_constant

But this includes a separator -- line between every line of desired text. Any easy ideas how to get rid of the -- lines?

Example: for an input file that looks like

line
line
nmse_gain_constant matching line
line after first match
line
line
nmse_gain_constant another matching line
line after second match
line
nmse_gain_constant a third matching line
line after third match

the output is

line after first match
--
line after second match
--
line after third match

but I'd like to have just

line after first match
line after second match
line after third match
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Michael
  • 851
  • 1
  • 6
  • 3

5 Answers5

117

I do this:

 grep ... | grep -v -- "^--$"

But this works too (on many, not all OS'es)!

grep --no-group-separator ...

And it doesn't spit out that "--" or even a blank line.

Erik Aronesty
  • 11,620
  • 5
  • 64
  • 44
  • 21
    `grep: unrecognized option '--no-group-separator'` on Mac OS X – krookedking Aug 28 '14 at 11:39
  • instead of adding additional grep just remove the `A` flag – Eddie Aug 09 '18 at 17:26
  • `--no-group-separator` is not supported by all versions of `grep` – Eric Nov 30 '18 at 17:15
  • 2
    For Mac OS X, you can install the Gnu versions of various command line tools using `brew`; this includes `grep`. I believe by default it is installed as `ggrep` (Gnu Grep). This supports the `--no-group-separator` option. I have done this and it works. See this link as a reference [How to install and use GNU Grep in macOS](https://apple.stackexchange.com/questions/193288/how-to-install-and-use-gnu-grep-in-macos#:~:text=104-,GNU,-grep%20is%20not) – steveb Jan 11 '22 at 16:15
25

There is an undocumented parameter of grep: "--group-separator", which overrides the default "--". You can set it to "" to get rid of the double dash. Though, you still get an empty line. I had the same trouble, and found this param by reading the source code of grep.

Shaohua Li
  • 259
  • 3
  • 2
  • 11
    You can use --no-group-separator (see below) – Erik Aronesty Aug 02 '12 at 16:42
  • even if I set `--group-separator=""`, the group separator is not actually empty, but still gets colored. So instead of an empty line, the separator line contains the color code, i.e `[[36m[[K[[m[[K`. Is there any way to disable coloring of the separator, while keeping grep `--color=always`? – Martin Vegter Feb 04 '14 at 15:41
  • 3
    there is no such option on mac for `grep (BSD grep) 2.5.1-FreeBSD` – Timofey Sep 29 '15 at 03:06
  • 1
    I can confirm Tim's statement - I've got the same version of grep and it is not available. – Peter Clark Feb 04 '16 at 21:20
  • why not just remove the `A` flag that adds this instead of additional processing. – Eddie Aug 09 '18 at 17:25
  • 1
    @eddie the `A` flag was needed for the search to find what the person was looking for. very often you're looking for "the line after something else" – Erik Aronesty Aug 23 '19 at 17:44
20

Well, the A switch by default will add those characters, so it's no mystery.

man grep states:

-A NUM

    Places  a  line  containing  a  group  separator  (--)   between
    contiguous  groups  of  matches.  With the -o or --only-matching
    option, this has no effect and a warning is given.

But you can use a simple sed to clean up the result:

yourgrep | sed '/^--$/d'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Eddie
  • 9,696
  • 4
  • 45
  • 58
  • 1
    Regexp with `sed` is overkill for this task. Why not use `grep -v -- --`? – Eric Nov 30 '18 at 17:13
  • The -A doesn't just add "--" it also prints NUM extra lines After the match. Similarly -B prints NUM lines Before the match, and -C prints NUM lines of Context from around the match. The "--" gets added to separate the groups. – creynia Mar 12 '19 at 14:30
  • This answer presumes the GNU version of grep. That excerpt of the man page, for instance, does not match at least BSD grep, GNU compatible 2.6.0-FreeBSD. Nor, in this version, is the `-A` flag exclusively responsible for the inclusion of the `--` separators. – Jason Hemann Nov 03 '22 at 14:20
8

There is no need to pipe to so many greps or use other tools (for example, sed) if you use AWK:

awk '/nmse_gain_constant/{getline;print }' compare.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • 2
    for grep -B use: awk '/regex/{ print x; print }; { x=$0 }' – D W May 05 '10 at 18:32
  • an explanation of the getline;print part of the awk command would suit this answer as most people who try to grep when they should awk are not familiar with the awk expressions used to obtain grep equivalent results – Steen Jun 23 '11 at 09:30
6

One solution will be:

grep -A 1 nmse_gain_constant compare.txt | grep -v nmse_gain_constant  | grep -v "\-\-"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Amirshk
  • 8,170
  • 2
  • 35
  • 64