分析混合单行和多行内容的日志

  • 本文关键字:日志 混合 单行 regex
  • 更新时间 :
  • 英文 :


我需要从日志文件中提取消息。消息以两种不同的方式记录:在一行中,如下所示:

2018-09-21 10:03:54,145 <message-content>
2018-09-21 10:05:02,008 <next-message-content>

或者像这样几行:

2018-09-21 10:03:54,145 <message-content-part 1>
<message-content-part 2>
...
<message-content-part n>
2018-09-21 10:04:12,198 <next-message-content>

每条消息都以标头d{4}-d{2}-d{2} d{2}:d{2}:d{2},d{3}开头。 每条消息中没有任何特定的结束标记。

我想提取所有消息,包括单行和多行,都有特定的文本。

例如,搜索"XYZ"的输出可能如下所示:

2018-09-21 10:03:54,145 AAA BBB XYZ CCC
2018-09-21 10:10:55,347 BBB 
CCC XYZW 
DDD
2018-09-21 10:12:56,060 EEE XYZFFF
GGG 

您可以使用

cat file | 
sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/nn&/' | 
awk 'BEGIN { RS = "nn"; ORS=""} /XYZ/ {print}'

观看在线演示

  • sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/nn&/'- 此 sed 命令查找以日期时间格式开头的行,并在它们前面加上双换行符
  • awk 'BEGIN { RS = "nn"; ORS=""} /XYZ/ {print}'- 此 awk 命令通过"\"(RS是记录分隔符(将文件拆分为记录时读取文件,并且仅打印(由于ORS=""而省略nn,其中ORS是输出记录分隔符(包含XYZ子字符串的那些。

使用 perl。我在示例输入中添加了另外 2 条消息,这些消息不应出现在输出中。

> cat pattern_xyz.dat
2018-09-21 10:03:54,145 AAA BBB XYZ CCC
2018-09-21 10:03:54,145 AAA BBB PPP CCC
2018-09-21 10:10:55,347 BBB
CCC XYZW
DDD
2018-09-21 10:12:56,060 EEE XYZFFF
GGG
2018-09-21 10:10:55,347 BBB
CCC QQQW
DDD
>
> cat pattern_xyz.pl
#!/usr/bin/perl
$file=$ARGV[0];
$x=`cat $file`;
while($x=~m/(^d{4}-d{2}-d{2})(.+?)(d{4}-d{2}-d{2})(.*)/osm)
{
$content="$1$2";
$x="$3$4";
if( $content=~/XYZ/  ) { print "$content"; }
}
> pattern_xyz.pl pattern_xyz.dat #executing script
2018-09-21 10:03:54,145 AAA BBB XYZ CCC
2018-09-21 10:10:55,347 BBB
CCC XYZW
DDD
2018-09-21 10:12:56,060 EEE XYZFFF
GGG
>
>

最新更新