继续包含关键字的awk或sed打印,直到达到结束模式

时间:2017-02-21 14:23:47

标签: bash shell unix awk sed

我有大量长不规则的日志,如下所示:

###<date> errortext <errorcode-xxxxx> 
errortext 
errortext 
errortext 
errortext
###<date> errortext <errorcode-yyyy>
errortext 
errortext 
###<date> errortext <errorcode-<zzzzzzz>
errortext 
errortext 
errortext 
errortext 
errortext 
errortext 
errortext 

长度不规则,需要使用grep / awk / sed或类似方法找到具有相同错误代码的错误。

我需要通过错误代码拆分这些文档,将一个代码的所有错误打印到一个文档中。

当我尝试使用如下行来查找整个错误代码段时:

sed -n '/#</{:start /###/!{N;b start};/<errorcode-024332>/p}' file

上述行的问题在于它只会打印包含&#34; errorcode-024332&#34;而不是所有的错误代码,直到下一个段开始(使用分隔符&#34; ###&#34;在这种情况下)。

我如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

您的问题发生是因为#<###都匹配“标题”行,所以您只打印它并且永远不会循环。您还会附加到模式缓冲区,而不是逐个使用这些行,因此无论如何都会始终匹配标题。

假设您要显示“errorcode-024332”的“标题”和“错误标记”,请按以下步骤操作:

sed -n '/#<.*<errorcode-024332>/{:start p;n;/###/!{b start}}'
  1. 当我们匹配与错误代码对应的标题行
  2. 我们打印它
  3. 我们得到下一行
  4. 如果下一行不包含###,我们将返回第2步。
  5. 我对您的示例数据进行了快速测试:

    $ echo "###<date> errortext <errorcode-xxxxx>
    errortext
    errortext
    [...]
    errortext
    errortext " | sed -n '/#<.*<errorcode-yyyy>/{:start p;n;/###/!{b start}}'
    
    ###<date> errortext <errorcode-yyyy>
    errortext
    errortext
    

答案 1 :(得分:2)

您可以使用http://blog.domain.com/?p=123,如下所示:

awk

让我将其解释为多行版本:

awk -F'[<>-]' '/^#/{f=$(NF-1)}{print >> f; close(f)}' file.log