【问题标题】:Grep "Exception" but filter out one specific case, based on previous lineGrep \"Exception\" 但根据前一行过滤掉一个特定案例
【发布时间】:2023-02-11 11:07:20
【问题描述】:

在我的应用程序中,我修改了所有的 IP 地址,以免干扰实际的生产系统。结果,我的应用程序抛出了很多异常。这些保存在名为filename 的日志文件中。

我想过滤异常,但我不想看到那些由IP地址修改引起的。

这听起来很简单,因为这些异常前面有一行,包含Failed to connect

让我们看看如何做到这一点:

过滤异常:

grep "Exception" filename

还显示上一行:

grep -B 1 "Exception" filename

不要显示包含“连接失败”的行:

grep -B 1 "Exception filename | grep -v "Failed to connect"

=> 不,这不是我想要的:这会过滤掉包含“无法连接”字样的行,但仍会显示实际的异常情况。我怎样才能不仅过滤掉异常呢?

我的filename内容是这样的:

... Failed to connect ...
... Exception ...
...
... (lots of these)
...
... <something else than "Failed to connect">
... Exception ...
...
... Failed to connect ...
... Exception ...
...
... (again lots of these)
...

我只对前面没有“连接失败”的... Exception ...行感兴趣。

当我按man grep时,它以:

GNU grep 3.4 ... 2019-12-29

有人有想法吗?
提前致谢

【问题讨论】:

  • 你也会考虑sedawk吗?
  • @anubhava:我确实会考虑awk,但我希望有一个纯粹的grep解决方案。我希望太多了吗? :-)

标签: regex grep windows-subsystem-for-linux


【解决方案1】:

使用 gnu-grep 你可以这样做:

grep -zoP '(?m)^(?!.*Failed to connect).+R.*Exception.*R' file

... foo bar baz
... Exception ...

# where file content is
cat file

.. Failed to connect ...
... Exception ...
...
... (lots of these)
...
... foo bar baz
... Exception ...
...
... Failed to connect ...
... Exception ...
...
... (again lots of these)
...

RegEx Demo

命令详细信息:

  • -z:一次对整个文件而不是一行进行操作
  • -o:只返回匹配的文本
  • -P:开启PCRE模式
  • (?m):启用多行模式
  • ^:匹配一行开始
  • (?!.*Failed to connect):当我们在一条线上的任何地方有Failed to connect时,否定前瞻断言失败
  • .+R:匹配 1+ 个后跟换行符的任意字符
  • .*Exception.*R:匹配 0+ 个任意字符,然后输入 Exception,然后再匹配 0 个或多个任意字符,后跟一个换行符

【讨论】:

  • 这么好的答案,我只能投一票。我讨厌这个网站 :-) :-) :-)
【解决方案2】:

使用您显示的示例,请尝试遵循 GNU awk 代码。在 GNU awk 中编写和测试,将 RS 设置为 [^ ]*\n[^E]*Exception[^ ]*,然后使用 match 函数根据 GNU awkRT 变量中显示的输出仅获取所需的部分。

awk -v RS='[^
]*\n[^E]*Exception[^
]*' '
RT{
  if(RT!~/Failed to connect/ && RT~/Exception/){
    match(RT,/(^|
)([^
]*
[^
]*$)/,arr)
    sub(/^
/,"",arr[1])
    print arr[1],arr[2]
  }
}
' Input_file

或者我们可以通过以下方式提高上述效率:

awk -v RS='[^
]*\n[^E]*Exception[^
]*' '
RT{
  if(RT!~/Failed to connect/ && RT~/Exception/){
    match(RT,/(^|
)([^
]*
[^
]*$)/,arr)
    print arr[2]
  }
}
' Input_file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多