使用 sed 和正则表达式处理多行日志文件

Posted

技术标签:

【中文标题】使用 sed 和正则表达式处理多行日志文件【英文标题】:Multiline log file processing with sed and regex 【发布时间】:2012-09-12 10:15:50 【问题描述】:

我有一个如下所示的日志文件:

11-Sep-2012 00:00:00 clojure.contrib.logging$fn__43$impl_write_BANG___51 invoke
INFO: creditAcc(args=[1506112834429596390 7080851004 4500])
11-Sep-2012 00:00:00 clojure.contrib.logging$fn__43$impl_write_BANG___51 invoke
INFO: callProf|tupsCredit|180|[1506112834429596390 7080851004 45]
11-Sep-2012 00:00:00 clojure.contrib.logging$fn__43$impl_write_BANG___51 invoke
INFO: creditAcc(args=[1506112834429596390 7080851004 4500]) -> done.
11-Sep-2012 00:00:00 clojure.contrib.logging$fn__43$impl_write_BANG___51 invoke
INFO: return(1506112834429596390,0)

日志文件中的每个条目跨越两行,因此每个条目都以时间戳开头。我已经设法使用 sed 替换了第一行末尾的换行符,但问题是日志条目中间的某个地方是 java stacktrace 消息。当 sed 通过堆栈跟踪时,它会反转条目的顺序,它们以 INFO 或 ERROR 等开头,时间戳显示为第二行。因此,我正在寻找一种解决方案,该解决方案将强制 sed 使用正则表达式 [类似于 ^\d2] 将时间戳识别为第一行,然后在同一行中,将换行符替换为空格,然后将值分解为用于分析的列。堆栈跟踪消息以空格 [^\s] 开头,因此很容易识别和跳过。

使用 sed 或 awk 解决此问题的最佳方法是什么?

【问题讨论】:

如果您显示一些带有堆栈跟踪的输入会很有帮助。 【参考方案1】:
sed '/^ /d; N; s/\n/ /' inputfile

这匹配以空格开头的行并删除它们。 d 指令跳过其余指令。如果一行不以空格开头,则下一行也被读入,并且它们之间的换行符变为空格。

只有当日志行成对时才能正常工作。换句话说,如果堆栈跟踪行跟在时间戳行之后,并且 INFO/ERROR 行出现在堆栈跟踪之后,它将无法正常工作。

【讨论】:

@Saichovsky:不客气。如果您单击我的答案旁边的复选标记,则会将其标记为已接受。

以上是关于使用 sed 和正则表达式处理多行日志文件的主要内容,如果未能解决你的问题,请参考以下文章

sed命令和正则表达式

Shell编程之正则表达式(sed)

sed多行文本处理

正则表达式 - grep、sed、awk - 处理大型文本文件

使用正则表达式解析日志文件

正则表达式sed学习