【问题标题】:How do I grep and filter logs for date and a particular field如何 grep 和过滤日期和特定字段的日志
【发布时间】:2019-09-10 15:19:12
【问题描述】:

我的日志会有一些格式如下的行

test/blah.log.32:30141:2019-08-12 16:40:09,839 com.test.service.testService [P1-7XX8] INFO testMethod(): userId: 12345XX, someOtherId: 12345XXXCCCDDD, blah, blah...., _someType=V, blah, blah, blah....

如何使用 grep 查找包含文本 _someType=V 的数据,然后从中过滤日期和用户 ID。我的最终结果应该是

2019-08-12 16:40:09,839-12345XX

我可以使用 grep -Hn '_someType=V' 进行 grep,但无法过滤数据。

【问题讨论】:

  • 文件文本以30141:test/blah.log.32: 开头?
  • @anubhava 最有可能使用2019-08-12 16:40:09,839 com.test...test/blah.log.32 是文件名,30141 是行号,分别由grep-H-n 输出跨度>
  • 将多个 grep 链接在一起? grep '_someType=V file | grep 2019-09-10' | grep userID ?使用-o 选项将输出限制为您的搜索目标。
  • @shellter 如果 OP 想要检索的两条数据是连续的,那将起作用。由于它们不是你不能用-o 选择它们,你必须使用sed 来删除两条数据之间的内容
  • @Aaron :我正在将示例日志数据作为一条连续线读取。但是......太糟糕了,数据没有更好地呈现,因此解释上没有差异。但我喜欢以下两种解决方案,并希望它们对 O.P. 有用。祝大家好运。

标签: regex shell awk sed grep


【解决方案1】:

您可以将grep 命令的输出通过管道传输到sed 以将整行转换为两个相关的数据:

grep '_someType=V' | sed -E 's/^([^ ]* [^ ]*).*userId: ([^ ]*).*/\1-\2/'

sedsubstitution 命令将日期对应的行的前两个“单词”捕获到第一个捕获组中,将userId 后面的单词捕获到第二个捕获组中,匹配整行以替换用破折号分隔的两个捕获组的内容。

如果_someType=VuserId 之间的顺序始终相同,则可以不使用grep,例如如果_someType=V 始终出现在userId 之后:

sed -nE 's/^([^ ]* [^ ]*).*userId: ([^ ]*).*_someType=V.*/\1-\2/p'

【讨论】:

    【解决方案2】:

    您可以使用awk:

    awk -v s='userId: ' '/_someType=V/ && match($0, s "[^, ]+") {
       print $1, $2 "-" substr($0, RSTART+length(s), RLENGTH-length(s))
    }' file
    

    2019-08-12 16:40:09,839-12345XX
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2017-01-15
      • 2020-11-30
      • 2011-07-12
      • 2014-03-22
      相关资源
      最近更新 更多