178.139.20.52 - - [26/Nov/2011:08:21:13 +0000] "POST /test/LinkTest.cgi?e=PATTERN&t3=0:010015&t4=1322295671:587875&l=178.139.20.174&n=149 HTTP/1.1" 200 17 "-" "BOT/1.26"
以上是我要解析的日志条目类型。
我喜欢输出命令:
178.139.20.52 PATTERN
关于如何实现这一目标的任何想法?
谢谢。
感谢您的回答,我将会这样做:
cat access_log | grep "LinkTest.cgi" | grep "26\/Nov\/2011" | awk -v FS="[ =&]" '{ print $1,$8 }' | sort -u
答案 0 :(得分:2)
使用GNU sed
的方法怎么样?
sed -r 's/^(\S+).*e=([^&]+)&.*/\1 \2/'
答案 1 :(得分:2)
如何使用awk
注意 - 如果您的pattern
不包含=
,space
或&
,这将有效。
awk -v FS="[ =&]" '{ print $1,$8 }' file
[jaypal:~/Temp] cat file
178.139.20.52 - - [26/Nov/2011:08:21:13 +0000] "POST /test/LinkTest.cgi?e=PATTERN&t3=0:010015&t4=1322295671:587875&l=178.139.20.174&n=149 HTTP/1.1" 200 17 "-" "BOT/1.26"
[jaypal:~/Temp] awk -v FS="[ =&]" '{ print $1,$8 }' file
178.139.20.52 PATTERN
答案 2 :(得分:2)
我认为grep不适合这个,它只根据模式过滤行。您可以使用-o
开关仅打印与该模式匹配的文本,但我不知道如何在grep中提取/打印多个子字符串。
这个perl one liner怎么样?
perl -ne 'm/^\s*(\d+\.\d+\.\d+\.\d+).+?\?e=([^&]+)/ and print "$1 $2\n"'
答案 3 :(得分:2)
这个问题似乎没有具体说明,因为我们不知道PATTERN
中的内容。这是一个起点:
sed -e 's/ .*LinkTest.cgi?e=/ /' -e 's/&.*//'
答案 4 :(得分:1)
使用awk:
'infile'的内容
178.139.20.52 - - [26/Nov/2011:08:21:13 +0000] "POST /test/LinkTest.cgi?e=PATTERN&t3=0:010015&t4=1322295671:587875&l=178.139.20.174&n=149 HTTP/1.1" 200 17 "-" "BOT/1.26"
我的linux机器中的awk命令:
awk 'BEGIN { FS = "=" } { ip = substr( $1, 0, index( $1, " " ) - 1 ); pattern = substr( $2, 0, index( $2, "&" ) - 1 ); printf "%s %s\n", ip, pattern }' infile
结果:
178.139.20.52 PATTERN