I am trying to write an awk script that can get a block that contains the word “error”, out of a long log file.
Basically this log file contains actions performed, and when one of these fails, it will add under the action the error line, saying what is wrong.
I can isolate easily the error line just doing a grep for “error:”, but i am missing the command given since it is printed before the error line, and i do not know how many lines before, so cannot just arbitrarily say “print the 10 lines that precede the word “error:”
I’ve figured out a sort of scheme thou; each of the block that could contain the error lines starts in the same way (“ProcessName”), followed by the command and other parameters, each one on a different line, and the last line will always be an empty line.
So my idea is to use this block with awk, so i can look for the “processName” string, start to print the lines one by one until i reach the empty line, and then pipe the printed result trough a grep to see if there is the word “error:” in there; if there is an error then i will redirect on a file and append the whole block, otherwise it will continue to the next block and do the same thing.
Now it would really help if i can get a hand with this task; since I do not really know how could I achieve this; I’ve just looked at awk and it seems to be the right tool for the job (i can write a shell script for the task), but if you think that there is a better way to do it in a shell script, I am all ears 🙂
Thanks in advance for your help!
Update: Thanks for your scripts; i’ve got the one from Dennis to work but it prints the same block more than once, if there is more than one error entry in each block; while the example from bellisarius does not return any line.
I’ve added an example of what my log looks like, when i introduce an error (there is an empty line at the end, but cannot add it if i put the text in the tag code):
ProcessName
ID=1231
Command:"ls -l a"
Hash "gkfsmgflsdmgklsdmfldsmfklmdsflkmsdflmsdflkmsdflkmsdfklsdmfklsdmfklmsdfklmsdklfmsdklmflksdmflkdsmfkldsmfkldmslfmdslkfmklsdmflksdmfklsdmfkldmslfkmslfkmsdlkfm"
/filename/compileme.c:20: error: the directory does not exist
/filename/compileme.c:20: error: incorrect parameter
A regular block looks exactly the same, but does not have the error: part obviously.
Hope that this makes it more clear, thanks again!
You may try:
Test:
Input:
Output:
Running at ideone here
Edit
On your comment about having sometimes an empty record before the error record, you can solve that by pre-processing your log files with the following awk script that deletes the empty lines before the error messages:
and then running the main script on the output of this one.