【问题标题】:How to only return specific text from grepping [closed]如何仅从 grepping 返回特定文本 [关闭]
【发布时间】:2016-03-17 02:00:46
【问题描述】:

我对 Linux Bash 脚本非常陌生,我现在正在做的是在日志文件中查找错误。我怎样才能只返回每个日志的时间而不是显示它的所有详细信息?以下是我的代码:

grep -n "Servlet.service() for servlet default threw exception" error 

日志文件的结果之一:

337:17:44:59,136 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/mobilelife].[default]] (http-/0.0.0.0:28080-32) JBWEB000236: Servlet.service() for servlet default threw exception:java.lang.reflect.UndeclaredThrowableException

而我想要的结果就是时间,17:44:59,有人可以帮忙吗?

【问题讨论】:

  • 请复制/粘贴文本而不是图像,以便测试答案脚本。
  • 等等,你只是想要每一行的时间,还是包含ERROR的任何行的时间戳?
  • 我想要任何包含 ERROR 的行的时间!

标签: linux bash terminal grep


【解决方案1】:

如果您在日志文件中搜索特定文本,例如:Servlet.service() for servlet default threw exception,并且文件中有许多其他条目,您将需要消除除包含搜索字符串的行之外的所有其他行的打印,并且然后只从该行输出相关时间。你可以这样做:

sed -n '/Servlet.service() for servlet default threw exception/s/^[^:]*:\([^,]*\).*$/\1/p' log.file

基本上是:

  • -n 禁止打印图案空间

  • /your search string/在文件中查找具体字符串

  • s/^[^:]*:\([^,]*\).*$/\1/ 仅使用 反向引用

  • p 打印该行

示例日志文件内容

$ cat log.file
37:17:44:59,136 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/mobilelife].[default]] (http-/0.0.0.0:28080-32) JBWEB000236: Servlet.service() for servlet default threw exception:java.lang.reflect.UndeclaredThrowableException
37:17:45:00,136 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/mobilelife].[default]] (http-/0.0.0.0:28080-32) JBWEB000236: Servlet.service1() for servlet default threw exception:java.lang.reflect.UndeclaredThrowableException
37:17:45:01,136 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/mobilelife].[default]] (http-/0.0.0.0:28080-32) JBWEB000236: Servlet.service2() for servlet default threw exception:java.lang.reflect.UndeclaredThrowableException

sed 使用/输出

$ sed -n '/Servlet.service() for servlet default threw exception/s/^[^:]*:\([^,]*\).*$/\1/p' log.file
17:44:59

【讨论】:

    【解决方案2】:

    从 grep 中仅获取匹配项本身的方法是 -o 选项,因此您可以首先找到包含 ERROR 的所有行并将其通过管道传输到另一个 grep 实例以获取时间戳:

    grep 'ERROR' error | grep -o '^[^,]*'
    

    第二个命令的正则表达式是“从行首 (^) 匹配尽可能多的非逗号 ([^,]) (*)”。

    您也可以使用逗号作为分隔符通过管道传递到cut,只打印第一个字段:

    grep 'ERROR' error | cut -d , -f 1
    

    或者,使用 Perl 正则表达式的 -P 选项将所有内容放在一个命令中:

    grep -Po '^[^,]*(?=.*ERROR)' error
    

    括号中的表达式是“前瞻”:该行必须包含.*ERROR,但它不会成为匹配的一部分。

    【讨论】:

    • 不,不只是这个日志记录,我需要所有的时间来自日志文件!
    • 如果同一个文件中有10000行包含Servlet.someotherservice()怎么办?
    • @DavidC.Rankin 是写给我的吗?
    • @BenjaminW。是的,抱歉,本杰明,这是给你的。
    • @DavidC.Rankin 我已经更新了答案。据我了解 OP,他们想要包含 ERROR 的任何行的时间戳。
    【解决方案3】:

    假设时间模式没有出现在其他地方

    grep -oP "(?<=:)(\d{2}:){2}\d{2}(?=.*ERROR)"
    

    awk 来救援!

    $ awk -F, '/ERROR/{sub(/^[0-9]+:/,""); print $1}' log
    17:44:59
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-19
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多