根据内容删除两行之间的文本块

时间:2012-12-02 14:04:50

标签: bash sed awk

我需要删除/过滤一个非常大的日志文件 我设法将日志文件放入文本块中,从包含<---->的行开始,该行以包含Content-Length:的行结尾 现在,如果这个文本块包含单词REGISTER,则需要将其删除。

我找到了流动的例子:

 # sed script to delete a block if /regex/ matches inside it
 :t
 /start/,/end/ {    # For each line between these block markers..
    /end/!{         #   If we are not at the /end/ marker
       $!{          #     nor the last line of the file,
          N;        #     add the Next line to the pattern space
          bt
       }            #   and branch (loop back) to the :t label.
    }               # This line matches the /end/ marker.
    /regex/d;       # If /regex/ matches, delete the block.
 }                  # Otherwise, the block will be printed.
 #---end of script---

由Russell Davies在this页面上撰写

但我不知道如何将其传输到单个行语句以在管道中使用 我的目标是将tail -F日志文件传输到最终版本,以便按分钟获取更新

3 个答案:

答案 0 :(得分:3)

试试这个:

awk '/<--|-->/{rec=""; f=1} f{rec = rec $0 ORS} /Content-Length:/{ if (f && (rec !~ "REGISTER")) printf "%s",rec; f=0}' file

如果它没有达到您想要的效果,请提供您想要的更多信息以及样本输入和输出。

为了分解上述内容,这里的每个声明都在单独的行中,并带有一些注释:

awk '
   /<--|-->/ {rec=""; f=1} # find the start of the record, reset the string to hold it and set a flag to indicate we've started processing a record
   f {rec = rec $0 ORS}    # append to the end of the string containing the current record
   /Content-Length:/{      # find the end of the record
      if (f && (rec !~ "REGISTER")) # print the record if it doesn't contain "REGISTER"
         printf "%s",rec
      f=0                  # clear the "found record" indicator
   }
' file

如果您想要打印的记录之间有文本,只需为未找到的“找到”标志添加测试,并调用打印当前记录的默认操作(!f;

awk '/<--|-->/{rec=""; f=1} f{rec = rec $0 ORS} !f; /Content-Length:/{ if (f && (rec !~ "REGISTER")) printf "%s",rec; f=0}' file

答案 1 :(得分:2)

这可能适合你(GNU sed);

sed '/<--\|-->/!b;:a;/Content-Length/!{$!{N;ba}};//{/REGISTER/d}' file
  • /<--\|-->/!b如果某行不包含<---->则打印
  • :a;/Content-Length/!{$!{N;ba}}继续添加行,直到遇到字符串Content-Length或文件结尾。
  • //{/REGISTER/d}如果读入的行包含Content-LengthREGISTER删除它/他们正常打印它们。

答案 2 :(得分:1)

如果我得到了你需要的东西,你想过滤掉这个块,就是这个只打印块:

tail -f logfile | sed -n '/\(<--\|-->\)/,/Content-Length:/ p' 

如果你想删除它:

tail -f logfile | sed '/\(<--\|-->\)/,/Content-Length:/ d'