2012-06-10 28 views
8

我想从我的服务器日志中获取“GET”查询。在每行匹配后使用grep获取下一个WORD

例如,这是服务器日志

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] code 404, message File not fo$ 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 - 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] code 404, message File not fo$ 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 - 

当我尝试用简单的grep或awk中,

Adi:~ adi$ awk '/GET/, /HTTP/' serverlogs.txt 

它给出了

1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 - 
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 - 

我只是想显示:hello and ss

有没有什么办法可以做到这一点?

回答

8

假设你有GNU的grep,您可以使用Perl风格的正则表达式做了积极的回顾后:

grep -oP '(?<=GET\s/)\w+' file 

如果你没有的GNU grep,那么我只用SED提醒:

sed -n '/^.*GET[[:space:]]\{1,\}\/\([-_[:alnum:]]\{1,\}\).*$/s//\1/p' file 

如果你碰巧有GNU的sed(这将是奇怪的,如果你没有GNU grep的,但确实有GNU SED),可大大简化:

sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file 

这里的底线是,你当然不需要管道来实现这一点。 grepsed就足够了。

+0

太棒了。完美的作品!简短而简单。 –

5

在这种情况下,由于日志文件具有已知结构,因此一种选择是使用cut来拉出第7列(字段默认由选项卡表示)。

grep GET log.txt | cut -f 7 
+0

仍然显示整条线。 1.0.0.127.in-addr.arpa - [10/Jun/2012 15:32:27]“GET/hello HTTP/1.1”404 - 1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57]“GET/ss HTTP/1.1”404 - –

+0

嗯,它是空格还是制表符分隔?如果空格,使用'-d'''剪切以指定空格作为列分隔符。 –

+0

与** - d'**参数非常吻合。 –

1

使用管道而不是单个复杂的正则表达式通常更容易。这适用于你所提供的数据:

fgrep GET /tmp/foo | 
    egrep -o 'GET (.*) HTTP' | 
    sed -r 's/^GET \/(.+) HTTP/\1/' 

这条管道返回以下结果:

hello 
ss 

当然,还有其他的方法来完成这项工作,但这种公然的作品所提供的语料库。

2

使用管道如果使用grep:

grep -o /he.* log.txt | grep -o [^/].* 
grep -o /ss log.txt | grep -o [^/].* 

[^ /]表示提取的字母从grep的输出^符号之后

0
gawk '{match($7,/\/(\w+)/,a);} length(a[1]){print a[1]}' log.txt 
hello 
ss 

如果有gawk然后上述命令将使用match函数使用正则表达式选择所需的值并将其存储到数组a

0

我试图做到这一点,通过这一连接传来:https://www.unix.com/shell-programming-and-scripting/153101-print-next-word-after-found-pattern.html

摘要: 使用grep来查找匹配的行,然后用awk来查找模式,打印下一个字段:

grep pattern logfile | \ 
    awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' 

如果你想知道独特的事件:

grep pattern logfile | \ 
    awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' | \ 
    sort | \ 
    uniq -c 
相关问题