Try this:
$ tac infile | sed -n '/fish/,$p' |tac
In general case if you run below sed command, you will get all line from first matched pattern to end of input file.
$ sed -n '/fish/,$p' file
this is a some fish
this is a fishie
this is a fish
this is a lion
this is a cat
So my solution is: If we run tac
command on input file your last matched pattern will change to as first pattern. see the result of tac infile
:
$ tac infile
this is a cat
this is a lion
this is a fish
this is a fishie
this is a some fish
this is a goat
this is a cow
The tac
command is the same as cat
command, while tac
prints files in reverse order.
Now if we run our first sed command, you will get all lines first matched pattern to end of input file. like:
$ tac infile | sed -n '/fish/,$p'
this is a fish
this is a fishie
this is a some fish
this is a goat
this is a cow
Ok, finished. We only need to run tac
command again to reverse back the lines to original order:
$ tac infile | sed -n '/fish/,$p' |tac
this is a cow
this is a goat
this is a some fish
this is a fishie
this is a fish
Done!
A perl
approach (assuming your file is small enough to load into memory):
perl -0pe 's/.+?\n.*?LinearRec\(1, F{58}\).*?\n.*?\n//' file
The -0
makes perl
slurp the entire file, and the -p
tells it to print each input line after applying the script given by -e
. The script itself matches 58 F
s and the surrounding two lines and removes them.
Best Answer
Without keeping the line:
With keeping the line:
Though we may want to improve it a bit so that we quit and stop reading as soon as we've found the 3rd
foo
:sed
would be more cumbersome. You'd need to keep the count of foo occurrences as a number of characters in the hold space like:Keep:
Not keep: