在sed或awk中,如何处理logging分隔符,这些分隔符*可能*跨越多行?

我的日志文件是:

Wed Nov 12 blah blah blah blah cat1 Wed Nov 12 blah blah blah blah Wed Nov 12 blah blah blah blah Wed Nov 12 blah blah blah blah cat2 more blah blah even more blah blah Wed Nov 12 blah blah blah blah cat3 Wed Nov 12 blah blah blah blah cat4 

我想parsing出在第一行findcat的完整多行条目。 在sed和/或awk这样做的最好方法是什么?

即我想我的parsing产生:

  Wed Nov 12 blah blah blah blah cat1 Wed Nov 12 blah blah blah blah cat2 more blah blah even more blah blah Wed Nov 12 blah blah blah blah cat3 Wed Nov 12 blah blah blah blah cat4 

如果你说每个以空格开头的行都是使用(g)awk(这是从我的记忆中得到的),那么它可能包含一些小的拼写错误,为了更好的可读性和一些额外的换行符,

 awk " BEGIN { multiline = 0;} ! /^ / { if (whatever) { print; multiline = 1;} else multiline = 0; } /^ / {if (multiline == 1) print; } " yourfile 

在哪里检查你的输出是否应该发生(例如对于猫)。

假设您的日志文件不包含控制字符'\01''\02' ,并且续行只有四个空格,则以下内容可能有效:

 c1=`echo -en '\01'` c2=`echo -en '\02'` cat logfile | tr '\n' $c1 | sed "s/$c1 /$c2/g" | sed "s/$c1/\n/g" | grep cat | sed "s/$c2/\n /g" 

说明:这将用ASCII 1(一个不应该出现在日志文件中的控制字符)替换每个换行符,并用ASCII 2(另一个控制字符)替换每个换行符“newline-space-space-space-space”。 然后用换行符重新替换ASCII码1,所以现在每一个多行的序列都被放在一行中,旧的换行符被ASCII 2替换。这被grep为cat,然后ASCII 2被替换为换行空间 – 空间 – 空间 – 空间组合。

像这样的东西?

 awk 'function print_part() { if(cat) print part } /^ / { part = part "\n" $0; next } /cat[0-9]$/ { print_part(); part = $0; cat = 1; next; } { print_part(); cat=0} END { print_part() }' inputfile 

/^ / regexp标识连续行。

/cat[0-9]$/ regexp标识您要保留的起始行。

另一种方法是将RS设置RS正常的\n 。 例如:

 $ awk -v Pre=Wed 'BEGIN {RS = "\\n?\\s*" Pre} /cat.\n?/ {print Pre $0}' file.log Wed Nov 12 blah blah blah blah cat1 Wed Nov 12 blah blah blah blah cat2 more blah blah even more blah blah Wed Nov 12 blah blah blah blah cat3 Wed Nov 12 blah blah blah blah cat4