我正在寻找一种方法来获取格式如下所示的access.log
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gig HTTP/1.0" 404 201
127.0.0.1 - frank [10/Oct/2000:13:56:40 -0700] "GET /apache_pb.gif HTTP/1.0" 200 1406
127.0.0.1 - frank [10/Oct/2000:13:57:45 -0700] "GET /apache_pb.gif HTTP/1.0" 200 5325
127.0.0.1 - frank [10/Oct/2000:13:58:16 -0700] "GET /apache_pb.gif HTTP/1.0" 200 35292
127.0.0.3 - jerry [10/Oct/2000:13:59:12 -0700] "GET /apache_pb.gif HTTP/1.0" 200 863
并编写一个脚本,返回如下格式的结果:
127.0.0.1 3
127.0.0.3 1
脚本的规则很简单,它应该计算每个唯一IP地址记录成功访问请求的次数(代码200)。
我完全愿意在狂欢之外做这件事。我只是觉得用grep、sort和uniq开始可能会更容易。我遇到的主要问题是uniq-c的输出格式错误。uniq一直在列出这样的输出:
3 127.0.0.1
1 127.0.0.3
不幸的是,我不能那样做。我们非常感谢任何帮助。谢谢
带awk:
awk '$(NF -1) == 200 {arr[$1]++}END{for (a in arr) print a, arr[a]}' access.log
稍微分解一下:
$(NF -1)
:awk
默认情况下在空格(或制表符等)上拆分当前行,NF
是列数,因此NF -1
是从右起的第二列,我们测试它的值是否为200- 如果是200,则我们以IP地址为关键字递增关联数组
arr
($1
:第一列) - @最后,我们打印每一条成功的线条
我认为脚本是一个标记,所以这里有一个小的python脚本来实现这一点。
file_name = "access.log"
ip_counts = {}
with open(file_name) as logfile:
_ = logfile.readlines()
for line in _:
try:
ip_counts[line.split()[0]] += 1
except Exception:
ip_counts[line.split()[0]] = 1
for ip in ip_counts:
print "%s %s" % (ip, ip_counts[ip])
编辑:糟糕!完全忘记了200部分。现在就修复了。
file_name = "access.log"
ip_counts = {}
with open(file_name) as logfile:
_ = logfile.readlines()
for line in _:
if "200" in line.split():
try:
ip_counts[line.split()[0]] += 1
except Exception:
ip_counts[line.split()[0]] = 1
for ip in ip_counts:
print "%s %s" % (ip, ip_counts[ip])
你几乎做到了,我会使用uniq -c
和流编辑器(sed)来重新排序输出:
grep -E " 200 [0-9]+$" logfile | cut -d -f 1 | uniq -c | sed -re "s/^.*([0-9]+) (.*)$/2 1/"