Я пишу простую программу, которая будет анализировать файл журнала дампа пакета из WireShark в более удобочитаемую форму. Я делаю это с помощью 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))]
linelist - это список, созданный с помощью метода readlines (), поэтому каждая строка в файле является элементом в списке. Я повторяю его для всех случаев появления "### SERVER", затем захватываю все строки после него до следующей пустой строки (что означает конец пакета). Я, должно быть, делаю что-то не так, потому что не только find () не работает, но и мне кажется, что есть лучший способ получить все, что находится между ### SERVER и следующим появлением пустой строки.
Есть идеи?






Смотрим на документ file.readlines ():
file.readlines([sizehint])
Read until EOF using readline() and return a list containing the lines thus read. If the optional sizehint argument is present, instead of reading up to EOF, whole lines totalling approximately sizehint bytes (possibly after rounding up to an internal buffer size) are read. Objects implementing a file-like interface may choose to ignore sizehint if it cannot be implemented, or cannot be implemented efficiently.
и документ file.readline ():
file.readline([size])
Read one entire line from the file. A trailing newline character is kept in the string (but may be absent when a file ends with an incomplete line). [6] If the size argument is present and non-negative, it is a maximum byte count (including the trailing newline) and an incomplete line may be returned. An empty string is returned only when EOF is encountered immediately.
A trailing newline character is kept in the string - означает, что каждая строка в linelist будет содержать не более один новой строки. Вот почему вы не можете найти подстроку "\n\n" ни в одной из строк - ищите целая пустая строка (или пустую в EOF):
if myline in ("\n", ""):
handle_empty_line()
Примечание. Я попытался объяснить поведение find, но питоническое решение сильно отличается от вашего фрагмента кода.
Общая идея такова:
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
Это также хорошо работает с явным итератором. Таким образом, вложенные циклы могут обновлять состояние итератора, потребляя строки.
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:
У этого есть приятное свойство находить блоки, которые находятся в конце файла и не имеют пустой строки, завершающей их.
Кроме того, это довольно легко обобщить, поскольку нет явных переменных изменения состояния, вы просто переходите в другой цикл, чтобы впитать строки в других типах блоков.
лучший способ - использовать генераторы прочитать презентацию Генераторные хитрости для системных программистов Это лучшее, что я видел о парсинге журнала;)
Это тоже была моя первая мысль. Немного более свежая версия того же выступления находится по адресу dabeaz.com/generators-uk. У меня действительно было мечты о конвейерах генератора. (как это странно?).