What I’m trying to do: Make a bash script that performs some tests on my system, wich than reads some log files, and in the end points me some analyzes.
I have, for example, a log file (and although it’s not so big sometimes, I want to save proccess when possible) that has in the end something like this:
Ran 6 tests with 1 failures and 0 errors in 1.042 seconds.
Tearing down left over layers:
Tear down Products.PloneTestCase.layer.PloneSite in 0.463 seconds.
Tear down Products.PloneTestCase.layer.ZCML in 0.008 seconds.
And I already have this bash line, that takes the line I want (the one with failures and errors):
error_line=$(tac $p.log | grep -m 1 '1-9 .* \(failures\|errors\)')
Obs: Could anyone answer me if ‘tac’ passes the proccess to grep for each line of the file, or first it load the hole file on memory and than grep runs on the hole “memory variable”? Cause I was thinking in run the grep to each line, and when the line I want comes, I’d stop the “cating” proccess.
If it does work this way (“grepping” each line), when grep finds what it want (with the -m 1 option), it stops the tac proccess? How I’d do that?
Also, do you know a better way?
Continuing…
So, the result of the command is:
Ran 6 tests with 1 failures and 0 errors in 1.042 seconds.
Now, I want to check that both the ‘1’ AND the ‘0’ values on the $error_line variable are equal to 0 (like they’re not on this case), so that if any of them is different I can perform some other proccess to sinalyze that some error or failure was found.
Answers?
,
When grep
exits because the pattern is found, a SIGPIPE
is sent to tac
causing it to exit so it won’t continue to run needlessly.
read failures errors <<< $(tac $p.log | grep -Pom 1 '(?<= )0-9*(?= *(failures|errors))')
if $failures == 0 && $errors == 0
then
echo "success"
else
echo "failure"
fi
The grep
command will output only the numbers found preceding the words “failures” and “errors” without outputting any of the other text on the line.
Edit:
If your grep
doesn’t have -P
, change the first line above to:
read failures errors <<< $(tac $p.log | grep -om 1 ' 0-9* *\(failures\|errors\)' | cut -d ' ' -f 2
or, to use a variation of Ignacio’s answer, to:
read failures errors <<< $(tac $p.log | awk '/^Ran/ {printf "%s\n%s\n", $5, $8}'
,
awk:
/^Ran / {
print "No failures: " ($5 == 0)
print "No errors: " ($8 == 0)
}
,
for very big log files, its better to use grep
first to find the patterns you need, then awk
to do other processing.
grep "^Ran" very_big_log_file | awk '{print $5$8=="00"?"no failure":"failure"}'
Otherwise, just awk will do.
awk '{print $5$8=="00"?"no failure":"failure"}'