生成报文丢失报告的Python脚本

0 投票
3 回答
532 浏览
提问于 2025-04-20 19:42

假设有一个日志文件,里面记录了时间戳、IP地址和其他信息,格式如下:

22:30 1.1.1.2 buffer overflow
22:30 1.1.1.2 drops 10 packets
22:30 1.1.1.3 drops 15 packets
22:35 1.1.1.2 drops 20 packets 

我想解析这个日志,并输出:

1.1.1.2 dropped a total of 30 packets
1.1.1.3 drooped a total of 15 packets

我开始是这样做的:

f = open('log.txt', 'r')
for line in f:
     if 'drops' in line:
     output = line.split()[1:]
     print output[1], output[3]

这样做会得到:

1.1.1.2 10
1.1.1.3 15
1.1.1.2 20

我不太确定怎么检查相同的IP地址,然后把数据包加起来。 有人能帮忙吗?谢谢!

3 个回答

1

把所有的IP地址收集起来,像字典一样把它们当作键,然后把丢包的数量当作值。

>>> ip_dict = {}
>>> with open('file.txt') as f:
...     for line in f:
...          if 'drops' in line:
...              output      = line.split()[1:]
...              ip          = output[0]
...              packet_lost = output[2]
...              if not ip_dict.get(ip,{}):
...                 ip_dict[ip] = 0
...              ip_dict[ip] += int(packet_lost)
... 
>>> 
>>> ip_dict
{'1.1.1.2': 30, '1.1.1.3': 15}

接着你可以遍历这些数据,并把输出格式化一下。

>>> for ip, total in ip_dict.iteritems():
...     print '%s dropped a total of %i packets' % (ip,total)
... 
1.1.1.2 dropped a total of 30 packets
1.1.1.3 dropped a total of 15 packets
2
with open('log.txt', 'r') as f:
    drops = {}
    for line in f:
         if 'drops' in line:
             time, ip, fn, n, packets = line.split()
             drops[ip] = drops.get(ip, 0) + int(n)
for ip, count in drops.items():
    print ip, count

这段代码的输出是:

1.1.1.2 30
1.1.1.3 15

关于这段代码,有两个要注意的地方:

  • 这段代码使用了Python的with语句,这样可以确保在不再需要文件时,它会被自动关闭。

  • 数据被拆分到一些有意义的变量中:

    time, ip, fn, n, packets = line.split()
    

    这样后面的代码就更容易理解了。

1

你可以使用defaultdict来实现这个功能。

from collections import defaultdict

d=defaultdict(int,{})
f = open('a.txt', 'r')
for line in f:
     if 'drops' in line:
         data=line.split()
         d[data[1]]=d.setdefault(data[1], 0)+ int(data[3])
f.close()
print d

输出

defaultdict(<type 'int'>, {'1.1.1.2': 30, '1.1.1.3': 15})

如果觉得defaultdict太复杂了,我们也可以直接用普通的字典(dict)。

d={}
f = open('a.txt', 'r')
for line in f:
     if 'drops' in line:
         data=line.split()
         d[data[1]]=d.setdefault(data[1], 0)+ int(data[3])
print d

撰写回答