我想从服务器日志中获取“ 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 -
当我尝试使用简单的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 -
我只想展示:你好和 ss
有什么办法可以做到吗?
答案 0 :(得分:12)
假设你有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,可以大大简化:
sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file
这里的底线是,你当然不需要管道来实现这一目标。 <{1}}或grep
就足够了。
答案 1 :(得分:6)
在这种情况下,由于日志文件具有已知结构,因此一个选项是使用cut
拉出第7列(默认情况下字段由制表符表示)。
grep GET log.txt | cut -f 7
答案 2 :(得分:3)
如果使用grep:
,请使用管道grep -o /he.* log.txt | grep -o [^/].*
grep -o /ss log.txt | grep -o [^/].*
[^ /]表示从grep输出
中提取^符号后面的字母答案 3 :(得分:2)
我试图这样做并遇到了这个链接: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
答案 4 :(得分:1)
使用管道而不是单个复杂的正则表达式通常更容易。这适用于您提供的数据:
fgrep GET /tmp/foo |
egrep -o 'GET (.*) HTTP' |
sed -r 's/^GET \/(.+) HTTP/\1/'
此管道返回以下结果:
hello
ss
当然还有其他方法可以完成工作,但这显然适用于所提供的语料库。
答案 5 :(得分:0)
gawk '{match($7,/\/(\w+)/,a);} length(a[1]){print a[1]}' log.txt
hello
ss
如果您有gawk
,那么上面的命令将使用match
函数使用正则表达式选择所需的值并将其存储到数组a
。