我的日志文件是:

 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

我想解析出在第一行找到cat的完整多行条目。在sed和/或awk

中执行此操作的最佳方法是什么?

即。我希望我的解析产生:

 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

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

其他提示

假设您的日志文件不包含控制字符'\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(一个永远不应出现在日志文件中的控制字符)替换每个换行符,每个序列<!> quot; newline-space-space-space-space <!> quot;使用ASCII 2(另一个控制字符)。然后它用换行符重新替换ASCII 1,所以现在每行的多行被放入一行,旧的换行符被替换为ASCII 2.这是针对cat的grepped,然后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

/^ /正则表达式标识连续行。

/cat[0-9]$/正则表达式标识您要保留的起始线。

另一种方法是将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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top