Найти - Пользователи
Полная версия: распарсить лог, поджскажите как
Начало » Python для новичков » распарсить лог, поджскажите как
1
Fixx_Jr
задача: обработать лог с экспортом в csv
лог выглядит так:
 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether f4:0f:24:29:df:4d 
	inet6 fe80::1cb5:1689:1826:cc7b%en0 prefixlen 64 secured scopeid 0x4 
	inet 10.176.85.19 netmask 0xffffff00 broadcast 10.176.85.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500
	options=60<TSO4,TSO6>
	ether 06:00:58:62:a3:00 
	media: autoselect <full-duplex>
	status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
	ether 06:0f:24:29:df:4d 
	media: autoselect
	status: inactive
csv должен быть таким:

interface,inet,status
lo0,127.0.0.1,
gif0,,
en0,10.176.85.19,active
en1,,inactive
p2p0,,inactive

подкиньте идей, как это можно сделать. Думаю, что надо разбить на кусочки(абзацы), а из них уже выжимать то, что есть в листы. Но не могу сообразить, как эти абзацы достать
py.user.next
Задача поставлена верно. Это важный критерий, потому что бывает неправильная постановка задачи в виде тумана или желе. Бывают ещё пластилиновые задачи - это когда она сейчас одна, через час становится другая вообще, а ещё через час - вообще третья. То есть это всё, что нужно устранять в задаче, прежде чем начинать её решать.

Fixx_Jr
Думаю, что надо разбить на кусочки(абзацы), а из них уже выжимать то, что есть в листы.
Вообще, такой класс задач гарантированно решается через конечные автоматы. У них там много всяких разновидностей. Так что если не можешь что-то сделать, то надо подтягивать теорию по ДКА (детерминированный конечный автомат). Если изучишь, будешь все такие задачи как орешки щёлкать.

Fixx_Jr
Но не могу сообразить, как эти абзацы достать
Надо обнаружить максимальные структуры, из которых состоят данные, и сделать код для их разделения. Затем надо одну такую структуру тоже делить и тоже на максимальные структуры, из которых она состоит, получив второй кусок кода. Так ты продолжаешь спускаться с максимального уровня структур до минимального уровня структур, пока не получишь самые простые элементы.

Да, тебе нужно все эти данные сначала разделить на записи. Получив список этих записей, нужно разделить саму запись на поля. Получив для каждой записи список её полей, нужно разделить само поле на имя и значение поля.

Так у тебя получится список списков списков - список записей в виде списков полей в виде списков имя значение. Можешь делать словарь, но словарь не упорядочен. В данной задаче порядок полей относительно друг друга в записи не важен, но в каких-то задачах этот порядок может иметь значение.

Можно это выдернуть всё и регулярными выражениями, даже одной штукой, но приучаться вообще решать такие задачи нужно именно классическим способом. Потому что сейчас оно сработает, а потом будет другая ситуация, где регулярное выражение не составишь. Также сейчас ты работаешь с текстом, а потом тебе надо будет работать точно так же, но только со списком событий. То есть декомпозиция задачи и конечный автомат может работать не только с текстом, а вообще с любой последовательностью - последовательностью символов, чисел, объектов, событий.

Так что начни с того, что разложи эти целые данные на отдельные записи, и код у тебя должен быть в итоге в виде функции, которая принимает целые данные, а возвращает список записей. Затем ты напишешь функцию, которая принимает одну запись и возвращает список её полей. Затем ты напишешь функцию, которая принимает одно поле и возвращает список имя поля и значение поля. И потом уже ты напишешь функцию, которая соединяет все эти три функции вместе и таким макаром получает из целых данных полностью разделённую структуру. И потом из неё ты уже можешь выбирать нужные тебе поля для сохранения в csv-файле.


tags: decomposition
uf4JaiD5
Fixx_Jr
Думаю, что надо разбить на кусочки(абзацы), а из них уже выжимать то, что есть в листы.
Я бы порезал по “: flags=”, а потом каждый кусок отдельно по “\n”.

А лучше использовать библиотеку.
Например, textfsm.
https://github.com/google/textfsm

https://github.com/google/textfsm/blob/master/examples/unix_ifcfg_example
https://github.com/google/textfsm/blob/master/examples/unix_ifcfg_template
Fixx_Jr
uf4JaiD5
Я бы порезал по “: flags=”, а потом каждый кусок отдельно по “\n”.

я бы тоже, но не знаю как ))

подскажите пожалста, как на абзацы(записи) разбить. всю голову сломал
vic57
типа так
 >>> out = []
>>> tmp =[]
>>> for i in s.split('\n'):
    if 'flags=' in i:
        out.append(tmp)
        tmp = []
        tmp.append(i)
    else: tmp.append(i)
    
>>> for i in out[1:]: print(i)
['lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384', '\toptions=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>', '\tinet 127.0.0.1 netmask 0xff000000 ', '\tinet6 ::1 prefixlen 128 ', '\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 ', '\tnd6 options=201<PERFORMNUD,DAD>']
['gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280']
['en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500', '\tether f4:0f:24:29:df:4d ', '\tinet6 fe80::1cb5:1689:1826:cc7b%en0 prefixlen 64 secured scopeid 0x4 ', '\tinet 10.176.85.19 netmask 0xffffff00 broadcast 10.176.85.255', '\tnd6 options=201<PERFORMNUD,DAD>', '\tmedia: autoselect', '\tstatus: active']
['en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500', '\toptions=60<TSO4,TSO6>', '\tether 06:00:58:62:a3:00 ', '\tmedia: autoselect <full-duplex>', '\tstatus: inactive']
>>> 
vic57
блин, очепятался
после цикла надо еще раз
 if tmp: out.append(tmp)
кстати видно, что блоки можно разбить по запятой
Fixx_Jr
vic57
блин, очепятался
после цикла надо еще раз
это чтобы последний абзац добавить?

а вообще супер, для меня это пока магия ))
vic57
Fixx_Jr
это чтобы последний абзац добавить?
ну да,
дальше уже парси каждый список типа так
 out = []
tmp = []
for i in s.split('\n'):
    i = i.strip()
    if 'flags=' in i and tmp:
        out.append(tmp)
        tmp = []
    tmp.append(i)
if tmp: out.append(tmp)
d = {}
for i in out:
    l = i[0].split(':')
    k = l[0].strip()
    i[0] = l[1].strip()
    d[k] = i
import json
print(json.dumps(d,indent=4))
 {
    "lo0": [
        "flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384",
        "options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>",
        "inet 127.0.0.1 netmask 0xff000000",
        "inet6 ::1 prefixlen 128",
        "inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1",
        "nd6 options=201<PERFORMNUD,DAD>"
    ],
    "gif0": [
        "flags=8010<POINTOPOINT,MULTICAST> mtu 1280"
    ],
    "en0": [
        "flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500",
        "ether f4:0f:24:29:df:4d",
        "inet6 fe80::1cb5:1689:1826:cc7b%en0 prefixlen 64 secured scopeid 0x4",
        "inet 10.176.85.19 netmask 0xffffff00 broadcast 10.176.85.255",
        "nd6 options=201<PERFORMNUD,DAD>",
        "media: autoselect",
        "status: active"
    ],
    "en1": [
        "flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500",
        "options=60<TSO4,TSO6>",
        "ether 06:00:58:62:a3:00",
        "media: autoselect <full-duplex>",
        "status: inactive"
    ],
    "p2p0": [
        "flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304",
        "ether 06:0f:24:29:df:4d",
        "media: autoselect",
        "status: inactive"
    ]
}
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB