2009-06-27 1 views
2

Linux上/proc/net/devの出力は次のようになります。各インターフェイスの値のペア:どのようにして/ proc/net/devの出力をPythonを使用してインターフェイスごとにkey:valueのペアに解析できますか?

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を使用することができますか?シェルスクリプトを使って達成するためにthis forum topicが見つかりましたが、a Perl extensionがありますが、Pythonを使用する必要があります。

答えて

10

これはきれいに書式設定された入力で、各行を分割して列とデータリストを簡単に取得し、それを表す辞書を作成できます。ここ

は、正規表現のない単純なスクリプトです

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'}} 
+0

を出力しますが、さらにインタフェース名をストライピングすることによってそれを改善し、フロートまたは第二のIについて –

+0

をintに値を変換することができますハスケルのように動作すると思っていましたが、残念ながらそれはしません:( – Armandas

+0

_はプレースホルダの変数名です、それはどのようにhaskellで動作しますか? –

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] 

あなたは、もちろん、dictsの辞書を構築するために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) 
+0

pythonバージョンありがとうございました。 –

関連する問題