【问题标题】:Grep Multiple words using a patternGrep 使用模式的多个单词
【发布时间】:2016-11-09 03:12:08
【问题描述】:

如果模式匹配,我需要从日志文件中 grep 多个字符串

下面是日志快照:access.log

12.12.137.16 - RMC1 [06/Jul/2016:07:34:17 -0700] "GET /identity/afr/partition/ie/n/default/opt/grid-11.1.1.9.0-5358.js HTTP/1.1" 200 9318 
12.12.137.16 - BMC1 [06/Jul/2016:07:34:17 -0700] "GET /identity/ HTTP/1.1" 200 6788 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:17 -0700] "GET /identity/afr/partition/ie/n/default/opt/status-11.1.1.9.0-5358.js HTTP/1.1" 200 2297 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:17 -0700] "GET /identity/afr/partition/ie/n/default/opt/poll-11.1.1.9.0-5358.js HTTP/1.1" 200 2098 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:18 -0700] "GET /identity/afr/alta-v1/overflow_right_ena.png HTTP/1.1" 200 1082 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:18 -0700] "GET /identity/ HTTP/1.1" 200 6749 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:18 -0700] "GET /identity/afr/alta-v1/conv_l_ena.png HTTP/1.1" 200 1161 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:24 -0700] "GET /identity/ HTTP/1.1" 200 6799 
12.12.137.16 - RMC1 [06/Jul/2016:07:34:27 -0700] "GET /identity/images/Dashboard/myAccess_s2.png HTTP/1.1" 200 6885 
12.12.137.16 - SSS1 [06/Jul/2016:07:34:24 -0700] "POST /identity/faces/home?_adf.ctrl-state=o9l9q161v_5 HTTP/1.1" 200 41776 

如果模式与日志文件中的 /identity /HTTP/1.1 匹配,则想要 grep 用户名和时间字段

所以我的输出将是:

BMC1 06/Jul/2016:07:34:17
RMC1 06/Jul/2016:07:34:18 
RMC1 06/Jul/2016:07:34:24

试过了:

grep -E '/identity/ HTTP/1.1' *.log

但它给出了整行。

请帮忙

【问题讨论】:

    标签: shell awk sed grep cut


    【解决方案1】:

    使用 awk

    $ awk -F'[][ ]+' '/\/identity\/ HTTP\/1[.]1/{print $3,$4}' access.log 
    BMC1 06/Jul/2016:07:34:17
    RMC1 06/Jul/2016:07:34:18
    RMC1 06/Jul/2016:07:34:24
    

    它是如何工作的:

    • -F'[][ ]+'

      这会将字段分隔符设置为[] 或空格的任意组合。

    • /\/identity\/ HTTP\/1[.]1/{print $3,$4}

      这会选择感兴趣的行并仅打印第三个和第四个字段。

    使用 sed

    $ sed -n '\|/identity/ HTTP/1[.]1|{s/^.* - //; s/[[]//; s/[]].*//; p;}' access.log 
    BMC1 06/Jul/2016:07:34:17 -0700
    RMC1 06/Jul/2016:07:34:18 -0700
    RMC1 06/Jul/2016:07:34:24 -0700
    

    它是如何工作的:

    • -n

      这告诉 sed 除非我们明确要求,否则不要打印任何内容。

    • \|/identity/ HTTP/1[.]1|

      这会选择感兴趣的行。

    • s/^.* - //; s/[[]//; s/[]].*//

      对于选定的行,这三个替换命令会从行中删除不需要的部分。

    • p

      这告诉 sed 在我们进行替换后打印所选行的剩余内容。

    使用grep -P

    如果您的 grep 支持 -P 标志:

    $ grep -oP '(?<= - ).*(?= "GET /identity/ HTTP/1\.1)' access.log 
    BMC1 [06/Jul/2016:07:34:17 -0700]
    RMC1 [06/Jul/2016:07:34:18 -0700]
    RMC1 [06/Jul/2016:07:34:24 -0700]
    

    如果去掉[]很重要,我们可以使用:

    $ grep -oP '(?<= - ).*(?=] "GET /identity/ HTTP/1\.1)' access.log | tr -d '['
    BMC1 06/Jul/2016:07:34:17 -0700
    RMC1 06/Jul/2016:07:34:18 -0700
    RMC1 06/Jul/2016:07:34:24 -0700
    

    【讨论】:

    • +1 以获得良好的答案,但请注意,您的 grep 答案并没有产生 OP 想要的结果。 OP 不想要 [] 字符。
    • 您需要在模式中转义 .,它现在将匹配两个 1 之间的任何字符(例如 1x1、131 等),这在这种情况下并不现实。
    • @karakfa 是的,谢谢,我错过了几个地方。答案已更新。
    • @sps 好点。我刚刚添加了一个grep+tr 解决方案来处理这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多