我试图从我的 Apache 日志中获取特定时间范围内的请求数量。我虽然用 sed
做这件事很容易但是当我尝试对 grep
做同样的事情时我意识到 grep
显示的结果多于 sed
.
这是grep
我使用的命令:
#grep '26/Apr/2017:08:0[0-2]:[0-2][0-4]' access.log
10.51.32.104 - - [26/Apr/2017:08:00:21 +0100] "GET / HTTP/1.1" 301 762 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
10.51.32.104 - - [26/Apr/2017:08:00:22 +0100] "GET /index.php?action=Login&module=Users HTTP/1.1" 200 6591 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET / HTTP/1.0" 301 1906 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET /index.php?action=Login&module=Users HTTP/1.0" 200 21951 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"
这是
sed
命令:#sed -n '/26\/Apr\/2017:08:00:21/ , /26\/Apr\/2017:08:02:04/p' access.log
10.51.32.104 - - [26/Apr/2017:08:00:21 +0100] "GET / HTTP/1.1" 301 762 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
10.51.32.104 - - [26/Apr/2017:08:00:22 +0100] "GET /index.php?action=Login&module=Users HTTP/1.1" 200 6591 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
172.30.180.113 - - [26/Apr/2017:08:02:04 +0100] "GET / HTTP/1.0" 301 1906 "-" "Mozilla/4.0 (compatible; ipMonitor 10.7)"
因此,如您所见,它缺少一个来自 172.30.180.113 的与该模式匹配的访问权限。
我做错了什么?在
sed
中会有任何其他参数有帮助,还是有更好的方法来做到这一点?
最佳答案
您已经非常接近使用 sed
解决它了.这是一个好的开始,我会鼓励你走这条路。
当然你可以用 regex
但它有其局限性。考虑范围 08:00
至 09:59
,正则表达式会很容易 0[89]:[0-5][09]
.但如果范围是 08:45
至 09:30
,然后 regex
不会是你的 friend 。因此,我鼓励您在尝试时使用该范围。
您在 sed
中看到的限制是满足结束范围和sed
已停止从那里处理。但是我们知道会有更多的线路落在结束范围内。
sed -n '/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{p;b};/26\/Apr\/2017:08:02:04/p' access.log
分解 sed 命令:
/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{p;b}
这将
p
如果在范围内,则打印该行然后 b
牧场到尽头sed
命令。/26\/Apr\/2017:08:02:04/p
仅当超出前一个
sed
的范围时才会执行此操作命令。这将处理落入范围内但未被 sed
考虑在范围内的额外行。 .相同的技术可以用于
awk
.awk '/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{a=NR;print};a!=NR && /26\/Apr\/2017:08:02:04/{print}' access.log
第一条命令:
/26\/Apr\/2017:08:00:21/,/26\/Apr\/2017:08:02:04/{a=NR;print}
将打印范围内的行并设置变量
a
到 NR
的值(当前记录号)。第二条命令:
a!=NR && /26\/Apr\/2017:08:02:04/{print}
将打印范围内的剩余行,但
awk
认为超出范围。
关于regex - SED 和 GREP 显示不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43663380/