3

我的日志文件是:

 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
4

4 回答 4

1

假设您的日志文件不包含控制字符'\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(一个永远不应出现在日志文件中的控制字符),并将每个序列“newline-space-space-space-space”替换为 ASCII 2(另一个控制字符)。然后它用换行符重新替换 ASCII 1,因此现在将多行的每个序列放入一行,用 ASCII 2 替换旧的换行符。这是 cat 的 grepped,然后 ASCII 2 被重新替换为换行-空格-空格-空格-空格组合。

于 2008-11-21T21:32:40.837 回答
1

如果您说以空格开头的每一行都是使用 (g)awk 轻松完成的后续操作(这是我的记忆,所以它可能包含一些小错别字,并且为了提高可读性,添加了一些额外的换行符):

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

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

于 2008-11-21T21:41:45.577 回答
0

像这样的东西?

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]$/则表达式标识您要保留的起始行。

于 2008-11-21T21:43:12.843 回答
0

另一种方法是设置RS为不同于 normal 的东西\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
于 2014-04-18T07:45:37.990 回答