【问题标题】:In sed or awk, how do I handle record separators which *may* span multiple lines?在 sed 或 awk 中,如何处理 * 可能 * 跨越多行的记录分隔符?
【发布时间】:2010-09-23 12:53:02
【问题描述】:

我的日志文件是:

 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

【问题讨论】:

  • 那么你如何定义逻辑行的结尾呢?是否有任何以空行开头的行自动被视为其上方行的扩展?

标签: linux sed awk gawk


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      这样的?

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

      【讨论】:

        【解决方案4】:

        另一种方法是将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
        

        【讨论】:

          猜你喜欢
          • 2018-11-02
          • 1970-01-01
          • 1970-01-01
          • 2011-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多