我需要从日志文件中提取消息。消息以两种不同的方式记录:在一行中,如下所示:
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
答案 0 :(得分:1)
您可以使用
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}/\n\n&/' | \
awk 'BEGIN { RS = "\n\n"; ORS=""} /XYZ/ {print}'
请参见online demo
详细信息
sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/\n\n&/'
-此sed命令查找以datetime格式开头的行,并在其前面加上双换行符awk 'BEGIN { RS = "\n\n"; ORS=""} /XYZ/ {print}'
-此awk命令通过“ \ n \ n”(RS
是记录分隔符)将文件拆分成记录来读取文件,并且仅打印(省略{{1} }的原因是\n\n
,其中ORS=""
是输出记录分隔符)包含ORS
子字符串的那些。答案 1 :(得分:-1)
使用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
>
>