sed或awk删除包含换行符的模式

时间:2019-04-10 01:36:13

标签: bash awk sed text-processing

我有一个与stderr结合在一起的日志文件,我正在尝试清理该文件。我可以隔离并找到stderr的“污染”,但是却在一个小细节上苦苦挣扎:删除换行符

这是我尝试还原的单独标准输出:

some message 1234556
more info foo bar

这是我试图摆脱stderr消息的组合stdout / stderr文件:

some message 1234/some/path ERROR
  more info only 1 line though
556
more info foo bar

所以这是我要摆脱的文字:

/some/path ERROR
more info only 1 line though

包括换行符,以便还原单独的标准输出。

我打电话:

# get rid of the line AFTER the stderr start
sed -i".bak" -e '/ERROR/{n;d}' *.log

# get rid of the start of stderr
sed -i".bak" -r 's/\/some\/path.*ERROR//' *.log

不幸的是,现在的输出是:

some message 1234
556
more info foo bar

请注意,stderr消息的插入点可以是任意的(在行的中间或在任何地方的开头)。我唯一可以假设的是stderr是两层的,它以/some/path开头,并包含一个错误标识符(ERROR或其他东西)。另外,随后可能会有多个stderr消息,例如:

some message 1234/some/path ERROR
  more info only 1 line though
/some/path ANOTHER_ERR
  more info only 1 line though
556
more info foo bar

我认为这并不是什么大问题(只有2种,所以我可以进行多个不同的匹配(ERRORANOTHER_ERR))。我也不关心使用sedawk ...

使用哪种工具。

4 个答案:

答案 0 :(得分:4)

您可以使用perl强大的段落模式选项。 -00命令行选项可打开段落浏览模式,这意味着Perl逐段读取文本, 而不是一行一行(一个段落是两个或多个换行符之间的文本。)

perl -00 -pe 's/\/.*(ERROR|ANOTHER_ERR)\n.*\n//g' file

要就地添加修改,请添加-i标志,类似于sed

perl -00 -pi -e 's/\/.*(ERROR|ANOTHER_ERR)\n.*\n//g' file

答案 1 :(得分:3)

对于-E和-z使用GNU sed:

$ sed -Ez 's:/some/path ERROR\n[^\n]+\n::g' file
some message 1234556
more info foo bar

,如果您要处理多个错误,则只需将其列出或在正则表达式中分隔:

$ cat file
some message 1234/some/path ERROR
  more info only 1 line though
/some/path ANOTHER_ERR
  more info only 1 line though
556
more info foo bar

$ sed -Ez 's:/some/path (ERROR|ANOTHER_ERR)\n[^\n]+\n::g' file
some message 1234556
more info foo bar

或者,对于多字符RS,使用GNU awk:

$ awk -v RS='/some/path ERROR\n[^\n]+\n' -v ORS= '1' file
some message 1234556
more info foo bar

或者,如果您愿意:

$ awk -v RS='^$' -v ORS= '{gsub("/some/path ERROR\n[^\n]+\n","")}1' file
some message 1234556
more info foo bar

答案 2 :(得分:2)

对于某些基本sed似乎是完美的。只需使用N将下一行插入模式空间即可。

sed '/ERROR/{N;s/\/.*//;N;s/\n//g}' input.log

  • N将下一行追加到图案空间
  • 删除正斜杠后的所有内容(包括下一行)
  • N将下一行追加到图案空间
  • 删除所有换行符

这与OP对n的尝试相距不远。

要将其扩展到以后的示例,您应返回到开始,以查看N命令是否在模式空间中引入了更多错误字符串:

sed -E ':a /(ERROR|ANOTHER_ERR)/{N;s/\/.*//;N;s/\n//g;b a}'

  • 使用-E允许在括号中使用两种模式
  • 添加标签:a
  • 每当在模式空间中发现并处理错误字符串时,
  • b a就会分支回到:a

我希望避免使用sed -z。它将整个文件读入模式空间,因此,如果此日志文件很长,或者您要将活动流通过管道传输到sed,则不是最佳选择。

答案 3 :(得分:1)

另一个没有this.setState({ events: evt1.concat(evt2) }) 选项的sed解决方案:

-z