如何使用Python将/proc/net/dev的输出解析为每个接口的键值对?
在Linux系统中,运行 /proc/net/dev 命令后,输出的内容大概是这样的:
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo:18748525 129811 0 0 0 0 0 0 18748525 129811 0 0 0 0 0 0
eth0:1699369069 226296437 0 0 0 0 0 3555 4118745424 194001149 0 0 0 0 0 0
eth1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我想知道怎么用Python来解析这个输出,把每个网络接口的信息转换成键值对的形式。我在网上找到了一些资料,比如这个论坛帖子讲的是怎么用Shell脚本来实现,还有一个Perl扩展,但我需要用Python来做。
3 个回答
1
这样做有帮助吗?
dev = open("/proc/net/dev", "r").readlines()
header_line = dev[1]
header_names = header_line[header_line.index("|")+1:].replace("|", " ").split()
values={}
for line in dev[2:]:
intf = line[:line.index(":")].strip()
values[intf] = [int(value) for value in line[line.index(":")+1:].split()]
print intf,values[intf]
输出结果:
lo [803814, 16319, 0, 0, 0, 0, 0, 0, 803814, 16319, 0, 0, 0, 0, 0, 0]
eth0 [123605646, 102196, 0, 0, 0, 0, 0, 0, 9029534, 91901, 0, 0, 0, 0, 0, 0]
wmaster0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
eth1 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
vboxnet0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
pan0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
当然,你可以使用header_names
中的标题名称来构建一个字典的字典。
1
好的,下面是你提供的内容:
#!/usr/bin/env python
from __future__ import with_statement
import re
import pprint
ifaces = {}
with open('/proc/net/dev') as fd:
lines = map(lambda x: x.strip(), fd.readlines())
lines = lines[1:]
lines[0] = lines[0].replace('|', ':', 1)
lines[0] = lines[0].replace('|', ' ', 1)
lines[0] = lines[0].split(':')[1]
keys = re.split('\s+', lines[0])
keys = map(lambda x: 'rx' + x[1] if x[0] < 8 else 'tx' + x[1], enumerate(keys))
for line in lines[1:]:
interface, values = line.split(':')
values = re.split('\s+', values)
if values[0] == '':
values = values[1:]
values = map(int, values)
ifaces[interface] = dict(zip(keys, values))
pprint.pprint(ifaces)
15
这是一个格式很整齐的输入,你可以通过把每一行拆分开,轻松获取到列和数据列表,然后把这些数据放到一个字典里。
下面是一个简单的脚本,没有使用正则表达式。
lines = open("/proc/net/dev", "r").readlines()
columnLine = lines[1]
_, receiveCols , transmitCols = columnLine.split("|")
receiveCols = map(lambda a:"recv_"+a, receiveCols.split())
transmitCols = map(lambda a:"trans_"+a, transmitCols.split())
cols = receiveCols+transmitCols
faces = {}
for line in lines[2:]:
if line.find(":") < 0: continue
face, data = line.split(":")
faceData = dict(zip(cols, data.split()))
faces[face] = faceData
import pprint
pprint.pprint(faces)
它的输出结果是
{' lo': {'recv_bytes': '7056295',
'recv_compressed': '0',
'recv_drop': '0',
'recv_errs': '0',
'recv_fifo': '0',
'recv_frame': '0',
'recv_multicast': '0',
'recv_packets': '12148',
'trans_bytes': '7056295',
'trans_carrier': '0',
'trans_colls': '0',
'trans_compressed': '0',
'trans_drop': '0',
'trans_errs': '0',
'trans_fifo': '0',
'trans_packets': '12148'},
' eth0': {'recv_bytes': '34084530',
'recv_compressed': '0',
'recv_drop': '0',
'recv_errs': '0',
'recv_fifo': '0',
'recv_frame': '0',
'recv_multicast': '0',
'recv_packets': '30599',
'trans_bytes': '6170441',
'trans_carrier': '0',
'trans_colls': '0',
'trans_compressed': '0',
'trans_drop': '0',
'trans_errs': '0',
'trans_fifo': '0',
'trans_packets': '32377'}}