Shell 使用一个模式Grep多个单词

Shell 使用一个模式Grep多个单词,shell,awk,sed,grep,cut,Shell,Awk,Sed,Grep,Cut,我有一个要求,如果模式匹配,我需要从日志文件中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 /iden

我有一个要求,如果模式匹配,我需要从日志文件中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
但它给出了整个路线

请使用awk协助

工作原理:

  • -F'[]+'

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

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

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

使用sed 工作原理:

  • -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]
使用awk 工作原理:

  • -F'[]+'

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

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

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

使用sed 工作原理:

  • -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]

+1表示好的答案,但请注意,您的
grep
答案并没有产生OP想要的结果。OP不需要
[
]
字符。您需要在模式中转义
,它现在将匹配两个1之间的任何字符(例如1x1、131等),这在这种情况下并不现实。@karakfa是的,谢谢,我错过了几个位置。答案很好。我刚刚添加了一个
grep+tr
解决方案来处理这个问题。+1是一个很好的答案,但只是一个提示,您的
grep
答案并没有产生OP想要的结果。OP不需要
[
]
字符。您需要在模式中转义
,它现在将匹配两个1之间的任何字符(例如1x1、131等),这在这种情况下并不现实。@karakfa是的,谢谢,我错过了几个位置。答案很好。我刚刚添加了一个
grep+tr
解决方案来处理这个问题。
$ 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