aaronstacy aaronstacy - 3 months ago 27
Bash Question

grep invert search with context

I want to filter out several lines before and after a matching line in a file.

This will remove the line that I don't want:

$ grep -v "line that i don't want"


And this will print the 2 lines before and after the line I don't want:

$ grep -C 2 "line that i don't want"


But when I combine them it does not filter out the 2 lines before and after the line I don't want:

# does not remove 2 lines before and after the line I don't want:
$ grep -v -C 2 "line that i don't want"


How do I filter out not just the line I don't want, but also the lines before and after it? I'm guessing
sed
would be better for this...

Edit: I know this could be done in a few lines of awk/Perl/Python/Ruby/etc, but I want to know if there is a succinct one-liner I could run from the command line.

Answer

Give this a try:

sed 'h;:b;$b;N;N;/PATTERN/{N;d};$b;P;D' inputfile

You can vary the number of N commands before the pattern to affect the number of lines to delete.

You could programmatically build a string containing the number of N commands:

C=2 # corresponds to grep -C
N=N
for ((i = 0; i < C - 1; i++)); do N=$N";N"; done
sed "h;:b;\$b;$N;/PATTERN/{N;d};\$b;P;D" inputfile