代码之家  ›  专栏  ›  技术社区  ›  davidmytton

如何使用Python将/proc/net/dev的输出解析为每个接口的键:值对?

  •  2
  • davidmytton  · 技术社区  · 17 年前

    产量 /proc/net/dev 在Linux上,如下所示:

    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
    

    this forum topic 为了使用shell脚本实现它,有 a Perl extension 但是我需要使用Python。

    3 回复  |  直到 17 年前
        1
  •  14
  •   Anurag Uniyal    17 年前

    这是非常格式化的输入,您可以很容易地通过拆分每一行来获得列和数据列表,然后创建一个dict。

    下面是一个没有正则表达式的简单脚本

    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'}}
    
        2
  •  1
  •   null    17 年前
    #!/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)
    
        3
  •  1
  •   wr.    17 年前

    这有用吗?

    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 构建一个dict的dict。