Удалить определенные строки из большого текстового файла в Python

У меня есть несколько больших текстовых файлов, которые имеют одинаковую структуру, и я хочу удалить первые 3 строки, а затем удалить недопустимые символы из 4-й строки. Я не хочу читать весь набор данных, а затем изменять его, поскольку каждый файл занимает более 100 МБ и содержит более 4 миллионов записей.

Range   150.0dB -64.9dBm
Mobile unit 1   Base    -17.19968    145.40369  999.8
Fixed unit  2   Mobile  -17.20180    145.29514  533.0
Latitude    Longitude   Rx(dB)  Best unit
-17.06694    145.23158  -050.5  2
-17.06695    145.23297  -044.1  2

Таким образом, строки 1,2 и 3 должны быть удалены, а в строке 4 "Rx(db)" должно быть просто "Rx", а "Best Unit" должно быть изменено на "Best_Unit". Затем я могу использовать другие мои скрипты для геокодирования данных.

Я не могу использовать программы командной строки, такие как grep ( как в этом вопросе), так как первые 3 строки не все одинаковые - числа (например, 150.0 дБ, -64*) будут меняться в каждом файле, поэтому вам нужно просто удалить все строки 1-3 и затем grep или аналогичные могут выполнить поиск-замену в строке 4.

Спасибо, парни,

=== РЕДАКТИРОВАТЬ новый питонический способ обработки больших файлов из @heltonbiker. Ошибка.

import os, re
##infile = arcpy.GetParameter(0)
##chunk_size = arcpy.GetParameter(1) # number of records in each dataset

infile='trc_emerald.txt'
fc= open(infile)
Name = infile[:infile.rfind('.')]
outfile = Name+'_db.txt'

line4 = fc.readlines(100)[3]
line4 = re.sub('\([^\)].*?\)', '', line4)
line4 = re.sub('Best(\s.*?)', 'Best_', line4)
newfilestring = ''.join(line4 + [line for line in fc.readlines[4:]])
fc.close()
newfile = open(outfile, 'w')
newfile.write(newfilestring)
newfile.close()

del lines
del outfile
del Name
#return chunk_size, fl
#arcpy.SetParameterAsText(2, fl)
print "Completed"

Трассировка (последний вызов был последним): Файл "P:\2012\Job_044_DM_Radio_Propogation\Working\FinalPropogation\TRC_Emerald\working\clean_file_1c.py", строка 13, в newfilestring = ''.join(line4 + [строка для строки в fc.readlines[4:]]) TypeError: объект builtin_function_or_method является неподписанным

3 ответа

Решение

Как сказал Вим в комментариях, sed это правильный инструмент для этого. Следующая команда должна делать то, что вы хотите:

sed -i -e '4 s/(dB)//' -e '4 s/Best Unit/Best_Unit/' -e '1,3 d' yourfile.whatever

Чтобы объяснить команду немного:

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

-e выполнить команду

'4 s/(dB)//' онлайн 4, заменить '' за '(dB)'

'4 s/Best Unit/Best_Unit/' То же, что и выше, за исключением различных строк поиска и замены

'1,3 d' от строки 1 до строки 3 (включительно) удалить всю строку

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

Просто попробуйте для каждого файла. 100 МБ на файл не так уж велики, и, как вы можете видеть, код, на который просто делается попытка, не требует много времени для написания.

with open('file.txt') as f:
  lines = f.readlines()
lines[:] = lines[3:]
lines[0] = lines[0].replace('Rx(db)', 'Rx')
lines[0] = lines[0].replace('Best Unit', 'Best_Unit')
with open('output.txt', 'w') as f:
  f.write('\n'.join(lines))

Ты можешь использовать file.readlines() с дополнительным аргументом, чтобы прочитать только несколько первых строк из файла. Из документов:

f.readlines () возвращает список, содержащий все строки данных в файле. Если задан необязательный параметр sizehint, он читает столько байтов из файла и еще достаточно, чтобы завершить строку, и возвращает строки из этого. Это часто используется для эффективного чтения большого файла построчно, но без необходимости загружать весь файл в память. Только полные строки будут возвращены.

Тогда самый надежный способ манипулировать общими строками - это регулярные выражения. В Python это означает re модуль с, например, re.sub() функция.

Мое предложение, которое должно быть адаптировано к вашим потребностям:

import re

f = open('somefile.txt')
line4 = f.readlines(100)[3]
line4 = re.sub('\([^\)].*?\)', '', line4)
line4 = re.sub('Best(\s.*?)', 'Best_', line4)
newfilestring = ''.join(line4 + [line for line in f.readlines[4:]])
f.close()
newfile = open('someotherfile.txt', 'w')
newfile.write(newfilestring)
newfile.close()
Другие вопросы по тегам