命令提取两行之间的数据

命令提取两行之间的数据

我必须从日志文件中的行号开始提取异常和相应的堆栈跟踪。我知道错误的起始行号。我如何从下面的示例中找出堆栈跟踪的结束位置?感谢你的帮助

例子
--------
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}

相关内容