Remove several lines from a text file based on a match

Today at work, I was asked for a way to emulate the Unix command "grep -v", but remove multiple lines that follow a match instead of just the matched line. Apparently, it was something that would help in cleaning up some output my coworker was dealing with. There were no limits on what method or language I could use, so I obviously chose Perl :-).

Here is my solution:

perl -ne '$a=3 if (/regex/); if ($a){--$a; next;} print' filename
command | perl -ne '$a=3 if (/regex/); if ($a){--$a; next;} print'

The parts in bold can be tweaked as needed:

  1. Set the number to the number of lines to be removed (including the matching line). I was originally asked to remove the two following lines, but this solution works for any number of following lines.
  2. Set the regex to an appropriate value to match what you want to discard.
  3. Set the filename or command to the appropriate value.

Here's how the solution works:

  1. Read the given file or command output one line at a time.
  2. If the unwanted text is found by the regex, a counter is set to the number of lines to skip. Note that the default value of the counter is undef. Also note that (by design) the counter gets reset every time it encounters the unwanted text, even if the counter is still set from finding another instance of the text.
  3. If the counter is set to any true value (anything except 0, empty string, or undef), the counter is decremented and the line is skipped.
  4. If the line wasn't skipped, it is printed.

The output can be piped to another command, sent to a file, etc. as needed.

I love one-liners.