2016-02-17 2 views
0

Я пытаюсь разобрать этот вывод ifconfig. Я видел еще один пример в Stack Overflow, где они делали этот же код, но он создает вложенный список. Однако, когда я делаю то же самое, я получаю только первые варианты соответствия. Кроме того, я хотел бы добавить RX и TX-пакеты в список и, похоже, не работает.Анализ вывода ifconfig с помощью python

Ifconfig выход

Mg0_RSP0_CPU0_0 Link encap:Ethernet HWaddr 70:e4:22:32:53:42 
      inet addr:20.200.130.1 Mask:255.255.0.0 
      inet6 addr: fe80::72e4:22ff:fe32:5342/64 Scope:Link 
      UP RUNNING NOARP MULTICAST MTU:1514 Metric:1 
      RX packets:147918 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:119226 errors:0 dropped:0 overruns:0 carrier:3 
      collisions:0 txqueuelen:1000 
      RX bytes:103741434 (98.9 MiB) TX bytes:5320623 (5.0 MiB) 

Tg0_0_0_7_0 Link encap:Ethernet HWaddr 78:ba:f9:35:66:46 
      inet addr:13.13.13.1 Mask:255.255.255.0 
      inet6 addr: fe80::7aba:f9ff:fe35:6646/64 Scope:Link 
      UP RUNNING NOARP MULTICAST MTU:1514 Metric:1 
      RX packets:26 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:5058 errors:0 dropped:0 overruns:0 carrier:3 
      collisions:0 txqueuelen:1000 
      RX bytes:1832 (1.7 KiB) TX bytes:454625 (443.9 KiB) 

Script

c = [] 
for paragraph in if_config_output.split('\n\n'): 

    ma = re.compile("^(\S+).*?inet addr:(\S+).*?Mask:(\S+)", re.MULTILINE|re.DOTALL) 

    result = ma.match(paragraph) 

    if result != None: 

     result = ma.match(paragraph) 

     interface = result.group(1) 
     ip = result.group(2) 
     mac = result.group(3) 

     #print "interface:", interface 
     #print "ip:",ip 
     #print "mask:", mask 

     c.append([interface, ip, mac]) 

print c 





In [145]: c 
Out[145]: [['Mg0_RSP0_CPU0_0', '1.83.53.27', '255.255.0.0']] 
+0

Я запустил ваш код (на _WIN_) и получил записи для обоих случаев. – CristiFati

ответ

1

Ну, я проверил свой код, и на первых получил один результат, второй один:

>>> ['Tg0_0_0_7_0', '13.13.13.1', '255.255.255.0'] 

Затем я внимательно посмотрел в том, что было в вашем регулярном выражении, и кажется, что у вас может быть новая новая строка перед вторым абзацем, как у меня было до моего первого, что заставило \ S остановиться. Вы можете исправить это (если я прав насчет причины, почему вы получаете единственный результат), добавив \ s? для начала Вашего регулярного выражения:

\s?^(\S+).*?inet addr:(\S+).*?Mask:(\S+) 

Или, если это случай простого интерфейса и поиска IP Вы можете использовать простой и быстрый раскол ...
Я даже timeit, если кто-то любопытно:

import timeit 
import re 

if_config_output = """ 
Mg0_RSP0_CPU0_0 Link encap:Ethernet HWaddr 70:e4:22:32:53:42 
      inet addr:20.200.130.1 Mask:255.255.0.0 
      inet6 addr: fe80::72e4:22ff:fe32:5342/64 Scope:Link 
      UP RUNNING NOARP MULTICAST MTU:1514 Metric:1 
      RX packets:147918 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:119226 errors:0 dropped:0 overruns:0 carrier:3 
      collisions:0 txqueuelen:1000 
      RX bytes:103741434 (98.9 MiB) TX bytes:5320623 (5.0 MiB) 

Tg0_0_0_7_0 Link encap:Ethernet HWaddr 78:ba:f9:35:66:46 
      inet addr:13.13.13.1 Mask:255.255.255.0 
      inet6 addr: fe80::7aba:f9ff:fe35:6646/64 Scope:Link 
      UP RUNNING NOARP MULTICAST MTU:1514 Metric:1 
      RX packets:26 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:5058 errors:0 dropped:0 overruns:0 carrier:3 
      collisions:0 txqueuelen:1000 
      RX bytes:1832 (1.7 KiB) TX bytes:454625 (443.9 KiB) 
""" 

ma = re.compile("^\s?(\S+).*?inet addr:(\S+).*?Mask:(\S+)", re.MULTILINE|re.DOTALL) 

def split(paragraph): 
    """ ugly, but faster """ 
    interface = paragraph.split(" Link ")[0] 
    inet_mask = paragraph.split("\n")[1].split(':') 
    ip, mask = inet_mask[1], inet_mask[2] 
    return [interface, ip, mask] 

def regex(paragraph): 

    result = ma.match(paragraph) 
    if result: 
     result = ma.match(paragraph) 
     interface = result.group(1) 
     ip = result.group(2) 
     mac = result.group(3) 
     return [interface, ip, mac] 

def test_split(): 
    c = [] 
    for paragraph in if_config_output.split('\n\n'): 
     c.append(split(paragraph)) 
    return len(c) 

def test_regex(): 
    c = [] 
    for paragraph in if_config_output.split('\n\n'): 
     c.append(regex(paragraph)) 
    return len(c) 

print ("split", timeit.timeit(stmt=test_split, number=100000)) 
print ("regex", timeit.timeit(stmt=test_regex, number=100000)) 

результаты

$ python --version 
Python 2.7.3 
$ python test.py 
('split', 3.096487045288086) 
('regex', 5.066282033920288) 
$ python3 --version 
Python 3.2.3 
$ python3 test.py 
split 4.155041933059692 
regex 4.875624895095825 
$ python3 test.py 
split 4.787220001220703 
regex 5.695119857788086 

Любой с Python 3.5 осторожно, чтобы присоединиться?

Да, странно неубедительно.

results from repl.it/languages/python3 (Python 3.4.0) 
split 1.2351078800020332 
regex 1.3363793969983817 

results from ideone.com (Python 2.7.9) 
('split', 0.9004449844360352) 
('regex', 0.7017428874969482) 

and from ideone.com (Python 3.4.3+) 
split 1.2050538789480925 
regex 1.7611852046102285 
+0

Спасибо, я попробовал ваше предложение по регулярному выражению, но получил следующий результат. Out [147]: [['Mg0_RSP0_CPU0_0', '1.83.53.27', '255.255.0.0']] – Matt

+0

И вы получаете данные из ifconfig напрямую или сохраняете результаты в строке? Добавьте следующий в свой цикл, чтобы узнать, что на самом деле вы получаете, и разместите здесь: 'print ("> {} <". Format (paragraph [: 5]))' – brainovergrow

+0

Чтобы ответить на ваш вопрос, я выполняю команду ifconfig в своем linux-окне , который хранит данные в переменной (if_config_output), вот вывод >>> В [170]: type (if_config_output) Out [170]: str – Matt

Смежные вопросы