我必须从日志文件中的行号开始提取异常和相应的堆栈跟踪。我知道错误的起始行号。我如何从下面的示例中找出堆栈跟踪的结束位置?感谢你的帮助
例子 -------- 2016-10-07 15:49:07,537 错误 一些异常 堆栈跟踪第 1 行 堆栈跟踪第 2 行 。 。 堆栈跟踪第 n 行 2016-10-07 15:49:07,539 调试等等等等 2016-10-07 15:49:07,540 调试等等等等
答案1
总而言之,您希望打印以您指定的行号开始的行,一直持续到下一个以日期开头的行之前。在您的示例中,起始行是 3。在这种情况下:
$ awk '{if (NR==3)f=1; else if (/^[0-9-]{10} /)f=0} f{print}' trace.log
2016-10-07 15:49:07,537 ERROR Some exception
stacktrace line 1
stacktrace line 2
.
.
stacktrace line n
上述代码的工作原理如下:
if (NR==3)f=1
在您指定的行号上,将变量设置
f
为 1。else if (/^[0-9-]{10} /)f=0
在其他行中,
f
如果该行以 10 个字符(数字或短划线后跟空格)开头,则设置为零。换句话说,f
在以日期开头的第一行设置为零。如果需要,我们可以使用更复杂的正则表达式来识别日期的开始。例如,以下内容要求该行以看起来像数据的内容开头,后跟一个空格,然后是看起来像时间的内容,最后跟一个逗号。
awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
对此还可以进一步改进。
f{print}
如果
f
非零,则打印该行。为简洁起见,我们可以
f{print}
仅替换为f
.这是可能的,因为当未明确指定操作时,print
将使用默认操作。
选择
某些版本的 awk 不支持重复因子,例如{10}
.如果您的系统出现这种情况,请尝试:
awk '{if (NR==3)f=1; else if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] /)f=0} f{print}' trace.log
答案2
假设所有堆栈跟踪行都以空格(空格/制表符)开头,您可以[[:blank:]]
在行的开头 ( )匹配它们 ( ) ^
:
grep '^[[:blank:]]' file.log
答案3
如果要提取的跟踪从 的第 2 行开始trace.log
,并且其结尾由以 YYYY-MM-DD 格式的日期开头的行表示(并且跟踪中没有此类行),则
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log
将从第 2 行开始打印每一行通过线n+3(跟踪后以日期开头的第一行)。由于您不需要最后一行,因此可以将上面的内容通过管道传输到删除最后一行的命令中:
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1
或者
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'
如果您需要搜索日期和一个时间,然后搜索
^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}