Grep from the end of a file to the beginning

filesgreptailtext processing

I have a file with about 30.000.000 lines (Radius Accounting) and I need to find the last match of a given pattern.

The command:

tac accounting.log | grep $pattern

gives what I need, but it's too slow because the OS has to first read the whole file and then send to the pipe.

So, I need something fast that can read the file from the last line to the first.

Best Answer

tac only helps if you also use grep -m 1 (assuming GNU grep) to have grep stop after the first match:

tac accounting.log | grep -m 1 foo

From man grep:

   -m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  

In the example in your question, both tac and grep need to process the entire file so using tac is kind of pointless.

So, unless you use grep -m, don't use tac at all, just parse the output of grep to get the last match:

grep foo accounting.log | tail -n 1 

Another approach would be to use Perl or any other scripting language. For example (where $pattern=foo):

perl -ne '$l=$_ if /foo/; END{print $l}' file

or

awk '/foo/{k=$0}END{print k}' file
Related Question