Справка по Python — Анализ журналов пакетов

Я пишу простую программу, которая будет анализировать лог-файл дампа пакетов из wirehark в более удобочитаемую форму. Я делаю это с помощью python.

В настоящее время я застрял в этой части:

for i in range(len(linelist)):
if '### SERVER' in linelist[i]:
    #do server parsing stuff

    packet = linelist[i:find("\n\n", i, len(linelist))]

список строк — это список, созданный с помощью метода readlines(), поэтому каждая строка в файле является элементом списка. Я перебираю его для всех вхождений «### SERVER», затем захватываю все строки после него до следующей пустой строки (что означает конец пакета). Должно быть, я делаю что-то не так, потому что не только не работает find(), но у меня есть ощущение, что есть лучший способ захватить все между ### SERVER и следующей пустой строкой.

Любые идеи?


person junkforce    schedule 16.11.2008    source источник


Ответы (4)


Глядя на документ file.readlines():

файл.readlines([sizehint])

Прочитайте до EOF, используя readline(), и верните список, содержащий прочитанные таким образом строки. Если присутствует необязательный аргумент sizehint, вместо чтения до EOF считываются целые строки, составляющие приблизительно байты sizehint (возможно, после округления до размера внутреннего буфера). Объекты, реализующие файловый интерфейс, могут игнорировать sizehint, если он не может быть реализован или не может быть реализован эффективно.

и документ file.readline():

файл.readline([размер])

Прочитать одну целую строку из файла. Завершающий символ новой строки сохраняется в строке (но может отсутствовать, если файл заканчивается неполной строкой). [6] Если аргумент размера присутствует и неотрицательен, это максимальное количество байтов (включая завершающий символ новой строки), и может быть возвращена неполная строка. Пустая строка возвращается только при немедленном обнаружении EOF.

A trailing newline character is kept in the string - означает, что каждая строка в linelist будет содержать не более одного символа новой строки. Вот почему вы не можете найти подстроку "\n\n" ни в одной из строк — ищите целую пустую строку (или пустую в EOF):

if myline in ("\n", ""):
    handle_empty_line()

Примечание. Я пытался объяснить поведение find, но решение на основе Python сильно отличается от вашего фрагмента кода.

person gimel    schedule 16.11.2008

Общая идея такова:

inpacket = False
packets = []
for line in open("logfile"):
  if inpacket:
    content += line
    if line in ("\n", ""): # empty line
      inpacket = False
      packets.append(content)
  elif '### SERVER' in line:
    inpacket = True
    content = line
# put here packets.append on eof if needed
person jfs    schedule 16.11.2008

Это также хорошо работает с явным итератором. Таким образом, вложенные циклы могут обновлять состояние итератора, потребляя строки.

fileIter= iter(theFile)
for x in fileIter:
    if "### SERVER" in x:
        block = [x]
        for y in fileIter:
            if len(y.strip()) == 0: # empty line
                break
            block.append(y)
        print block # Or whatever
    # elif some other pattern:

Это имеет приятное свойство находить блоки, которые находятся в хвостовой части файла и не заканчиваются пустой строкой.

Кроме того, это довольно легко обобщить, поскольку нет явных переменных изменения состояния, вы просто входите в другой цикл, чтобы впитывать строки в других типах блоков.

person S.Lott    schedule 16.11.2008

лучший способ - использовать генераторы читать презентацию Трюки с генераторами для системных программистов Это лучшее, что я видел по парсингу лога; )

person slav0nic    schedule 16.11.2008
comment
Это тоже была моя первая мысль. Чуть более свежая версия того же доклада находится по адресу dabeaz.com/generators-uk< /а>. На самом деле мне снились сны о конвейерах генераторов. (как это странно?). - person Peter Rowell; 16.11.2008