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.
In order to invert a grep expression, we just need to make use of the -v flag along with the grep command.
The long form of the flag -v is --invert-match .
Matching the lines that end with a string : The $ regular expression pattern specifies the end of a line. This can be used in grep to match the lines which end with the given string or pattern.
If the lines are all unique you could grep the lines you want to remove into a file, and then use that file to remove the lines from the original, e.g.
grep -C 2 "line I don't want" < A.txt > B.txt
grep -f B.txt A.txt
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
awk 'BEGIN{n=2}{a[++i]=$0}
/dont/{
for(j=1;j<=i-(n+1);j++)print a[j];
for(o=1;o<=n;o++)getline;
delete a}
END{for(i in a)print a[i]} ' file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With