在每行匹配后使用grep获取下一个WORD

adi*_*pta 12 linux grep

我想从我的服务器日志中获取" GET "查询.

例如,这是服务器日志

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 -
Run Code Online (Sandbox Code Playgroud)

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

Adi:~ adi$ awk '/GET/, /HTTP/' serverlogs.txt
Run Code Online (Sandbox Code Playgroud)

它给出了

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 -
Run Code Online (Sandbox Code Playgroud)

我只想显示:你好ss

有什么办法可以做到吗?

Tim*_*ote 14

假设你有gnu grep,你可以使用perl风格的正则表达式做一个积极的lookbehind:

grep -oP '(?<=GET\s/)\w+' file
Run Code Online (Sandbox Code Playgroud)

如果你没有gnu grep,那么我建议只使用sed:

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

如果您碰巧有gnu sed,那可以大大简化:

sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file
Run Code Online (Sandbox Code Playgroud)

这里的底线是,你当然不需要管道来实现这一目标. grepsed单独就足够了.


Joh*_*ter 8

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

grep GET log.txt | cut -f 7 
Run Code Online (Sandbox Code Playgroud)

  • 嗯,是空格还是制表符分隔?如果是空格,使用 `-d' '` 和 cut 来指定空格作为列分隔符。 (2认同)
  • 与 **-d ' '** 参数配合使用效果很好。 (2认同)

ajp*_*619 5

我试图这样做并发现了这个链接: 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)}'
Run Code Online (Sandbox Code Playgroud)

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

grep pattern logfile | \
  awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' | \
  sort | \
  uniq -c
Run Code Online (Sandbox Code Playgroud)