过滤access.log以返回每个客户端的唯一IP地址列表和成功请求数(代码200)的有效方法是什么?

时间:2013-11-29 20:30:33

标签: apache bash scripting awk

我正在寻找一种方法来获取如下所示格式化的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)。

我完全愿意在bash之外做这件事。我只是觉得用grep,sort和uniq开始可能更容易。我遇到的主要问题是输出uniq -c的格式错误。 uniq一直列出如下输出:

3  127.0.0.1
1  127.0.0.3

不幸的是,我无法做到这一点。任何帮助都非常感谢。谢谢!

3 个答案:

答案 0 :(得分:5)

使用

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,那么我们将关联数组arr增加为IP地址作为键($1:第一列)
  • @the end,我们打印每一条成功的行

答案 1 :(得分:1)

你得到它几乎我会使用uniq -c结合流编辑器(sed)来重新排序输出:

grep -E " 200 [0-9]+$" logfile | cut -d\  -f 1 | uniq -c | sed -re "s/^.*([0-9]+) (.*)$/\2 \1/"

答案 2 :(得分: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])