我正在尝试做的事情:创建一个bash脚本,在我的系统上执行一些测试,而不是读取一些日志文件,最后指出了一些分析。
例如,我有一个日志文件(虽然它有时候不是很大,但我想在可能的情况下保存过程),最终会有这样的事情:
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.
我已经有了这个bash行,它占用了我想要的行(有失败和错误的行):
error_line=$(tac $p.log | grep -m 1 '[1-9] .* \(failures\|errors\)')
Obs:如果'tac'将过程传递给文件的每一行grep,或者首先它将内核文件加载到内存而不是grep在“内存变量”上运行,那么有人可以回答我吗?因为我正在考虑将grep运行到每一行,当我想要的行出现时,我会停止“cating”进程。
如果它确实以这种方式工作(“grepping”每一行),当grep找到它想要的东西时(使用-m 1选项),它会停止tac过程吗?我怎么做的?
另外,你知道更好的方法吗?
...继续
因此,该命令的结果是:
Ran 6 tests with 1 failures and 0 errors in 1.042 seconds.
现在,我想检查$ error_line变量上的'1'和'0'值是否等于0(就像它们在这种情况下不一样),所以如果它们中的任何一个不同我可以执行一些其他过程来分析发现了一些错误或失败。
答案?
答案 0 :(得分:1)
当grep
因找到模式而退出时,会向SIGPIPE
发送tac
,导致其退出,因此无法继续不必要地运行。
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
grep
命令将仅输出在“失败”和“错误”之前找到的数字,而不输出该行上的任何其他文本。
修改强>
如果您的grep
没有-P
,请将上面的第一行更改为:
read failures errors <<< $(tac $p.log | grep -om 1 ' [0-9]* *\(failures\|errors\)' | cut -d ' ' -f 2
或者,使用Ignacio答案的变体来:
read failures errors <<< $(tac $p.log | awk '/^Ran/ {printf "%s\n%s\n", $5, $8}'
答案 1 :(得分:0)
AWK:
/^Ran / {
print "No failures: " ($5 == 0)
print "No errors: " ($8 == 0)
}
答案 2 :(得分:0)
对于非常大的日志文件,最好先使用grep
查找所需的模式,然后awk
进行其他处理。
grep "^Ran" very_big_log_file | awk '{print $5$8=="00"?"no failure":"failure"}'
否则,只是awk会这样做。
awk '{print $5$8=="00"?"no failure":"failure"}'