#python #awk #mbox
#python #awk #mbox
Вопрос:
Какой был бы наилучший Pythonic способ реализации этой команды awk в python?
awk 'BEGIN{chunk=0} /^From /{msgs ;if(msgs==500){msgs=0;chunk }}{print > "chunk_" chunk ".txt"}' mbox
Сейчас я использую это, чтобы разделить огромные файлы почтового ящика (формат mbox).
Прямо сейчас я пробую рекурсивный метод.
def chunkUp(mbox, chunk=0):
with open(mbox, 'r') as bigfile:
msg = 0
for line in bigfile:
if msg == 0:
with open("./TestChunks/chunks/chunk_" str(chunk) ".txt", "a ") as cf:
if line.startswith("From "): msg = 1
cf.write(line)
if msg > 20: chunkUp(mbox, chunk 1)
Я хотел бы иметь возможность реализовать это на python и иметь возможность возобновить выполнение, если оно прервано. Сейчас работаю над этим.
Я завязываю свой мозг в узлы! Приветствую!
Комментарии:
1. рекурсивный — это плохо, потому что файлы не закрываются (слишком много открытых файлов через некоторое время)
2. хороший момент, я отойду от этого подхода.
Ответ №1:
ваш рекурсивный подход обречен на неудачу: в конечном итоге у вас может оказаться слишком много открытых файлов одновременно, поскольку with
блоки не завершаются до конца программы.
Лучше открыть один дескриптор и записать в него, закрыть и повторно открыть новый дескриптор при обнаружении «From».
также открывайте свои файлы в режиме записи, а не добавления. Приведенный ниже код пытается выполнить минимальные операции и тесты для записи каждой строки в файл и закрыть / открыть другой файл, когда From:
будет найден. Также, в конце, закрывается последний файл.
def chunkUp(mbox):
with open(mbox, 'r') as bigfile:
handle = None
chunk = 0
for line in bigfile:
if line.startswith("From "):
# next (or first) file
chunk = 1
if handle is not None:
handle.close()
handle = None
# file was closed / first file: create a new one
if handle is None:
handle = open("./TestChunks/chunks/chunk_{}.txt".format(chunk), "w")
# write the line in the current file
handle.write(line)
if handle is not None:
handle.close()
Я не тестировал это, но это достаточно просто, это должно сработать. Если в первой строке файла нет «From», все предыдущие строки сохраняются в chunk_0.txt
файле.
Комментарии:
1. Я застрял при попытке использовать с open(). Это замечательное решение. Я буду реализовывать 500 сообщений на блок, как указано в команде awk, с помощью этого. Я отмечаю как отвеченный, поскольку он столкнулся с ментальным блоком обработки открытых файлов. Спасибо!