最近公司官网很不稳定,于是有一个需求,统计在apache访问日志下面的IP个数。
这个实现起来其实也就一条awk命令,可以这样写:
awk ‘{i=$1;count[i]++}END{for(i in count)print(i,count[i])}’ /var/log/httpd/access_log
awk对文件进行流处理,每次读取一行。$1就是IP,count[i]++是将IP作为一个数组的下标,并且使得统计这个IP所对应的数组元素自增1.END后面的语句是打印结果,只执行一次。
这里用Python也可以实现相同功能,并且更为灵活,体现在可以根据不同的正则匹配不同的内容,而且用字典key-value(key为IP,value为个数),比awk更为容易理解。统计哪个文件也可以作为参数输入到这个脚本。
函数式编程
#!/usr/bin/env python
import re
import sys
def countPatt(patt, fname):
db = {}
with file(fname)as f:
for eachLine in f:
m = re.search(patt,eachLine)
if m is not None:
dbKey = m.group()
db[dbKey] = db.get(dbKey,0) + 1
print db
return db
def test():
ip_patt = '^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
#ip_fname = '/var/log/httpd/access_log'
print countPatt(ip_patt, sys.argv[1])
if __name__=='__main__':
test()
面向对象编程
#!/usr/bin/env python
import re
import sys
class Counts(object):
def __init__(self, patt):
self.patt = patt
self.db = {}
def countPatt(self,fname):
with file(fname) as f:
for eachLine in f:
m = re.search(self.patt,eachLine)
if m is not None:
dbKey = m.group()
self.db[dbKey] = self.db.get(dbKey,0) + 1
return self.db
def test():
countip = Counts('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
print countip.countPatt(sys.argv[1])
countbrowsers = Counts('Firefox|Chrome')
print countbrowsers.countPatt(sys.argv[1])
if __name__=='__main__':
test()