I have a log file that may be very large (10+ GB). I'd like to find the last occurrence of an expression. Is it possible to do this with standard posix commands?
Here are some potential answers, from similar questions, that aren't quite suitable.
tail -n <x> <file> | grep -m 1 <expression>
: I don't know how far back the expression is, so I don't know what <x>
would be. It could be several GB previous, so then you'd be tailing the entire file. I suppose you could loop and increment <x>
until it's found, but then you'd be repeatedly reading the last part of the file.tac <file> | grep -m 1 <expression>
: tac reads the entire source file. It might be possible to chain something on to sigkill tac as soon as some output is found? Would that be efficient?If it helps, the expression is anchored at the start of a line, eg: "^foo \d+$"
.
Inverting Grep Expression In order to invert a grep expression, we just need to make use of the -v flag along with the grep command.
The quiet option ( -q ), causes grep to run silently and not generate any output. Instead, it runs the command and returns an exit status based on success or failure. The return status is 0 for success and nonzero for failure.
To use negative matching in grep , you should execute the command with the -v or --invert-match flags. This will print only the lines that don't match the pattern given.
For BSD or GNU grep you can use -B num to set how many lines before the match and -A num for the number of lines after the match. If you want the same number of lines before and after you can use -C num . This will show 3 lines before and 3 lines after.
Whatever script you write will almost certainly be slower than:
tac file | grep -m 1 '^foo [0-9][0-9]*$'
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