Я хочу перебрать содержимое текстового файла, выполнить поиск и замену в некоторых строках и записать результат обратно в файл. Я мог бы сначала загрузить весь файл в память, а затем записать его обратно, но это, вероятно, не лучший способ сделать это.
Каков наилучший способ сделать это в следующем коде?
f = open(file) for line in f: if line.contains('foo'): newline = line.replace('foo', 'bar') # how to write this newline back to the file
Переведено автоматически
Ответ 1
Вероятно, самым коротким способом было бы использовать модуль fileinput. Например, следующий добавляет номера строк в файл на месте:
import fileinput
for line in fileinput.input("test.txt", inplace=True): print('{} {}'.format(fileinput.filelineno(), line), end='') # for Python 3 # print "%d: %s" % (fileinput.filelineno(), line), # for Python 2
Здесь происходит следующее:
Исходный файл перемещается в файл резервной копии
Стандартный вывод перенаправляется в исходный файл внутри цикла
Таким образом, любые print инструкции записывают обратно в исходный файл
fileinput имеет больше наворотов. Например, его можно использовать для автоматической работы со всеми файлами в sys.args[1:], без необходимости перебирать их явно. Начиная с Python 3.2, он также предоставляет удобный контекстный менеджер для использования в with инструкции.
Хотя fileinput отлично подходит для одноразовых скриптов, я бы поостерегся использовать его в реальном коде, потому что, по общему признанию, он не очень удобочитаем или знаком. В реальном (производственном) коде стоит потратить еще несколько строк кода, чтобы сделать процесс явным и, таким образом, сделать код читабельным.
Есть два варианта:
Файл не слишком большой, и вы можете просто прочитать его полностью в памяти. Затем закройте файл, снова откройте его в режиме записи и запишите измененное содержимое обратно.
Файл слишком велик, чтобы его можно было сохранить в памяти; вы можете переместить его во временный файл и открыть его, читая построчно и записывая обратно в исходный файл. Обратите внимание, что для этого требуется вдвое больший объем памяти.
Ответ 2
Я предполагаю, что это должно быть сделано чем-то вроде этого. В основном это записывает содержимое в новый файл и заменяет старый файл новым файлом:
from tempfile import mkstemp from shutil import move, copymode from os import fdopen, remove
defreplace(file_path, pattern, subst): #Create temp file fh, abs_path = mkstemp() with fdopen(fh,'w') as new_file: withopen(file_path) as old_file: for line in old_file: new_file.write(line.replace(pattern, subst)) #Copy the file permissions from the old file to the new file copymode(file_path, abs_path) #Remove original file remove(file_path) #Move new file move(abs_path, file_path)
Ответ 3
Вот еще один пример, который был протестирован и будет соответствовать шаблонам поиска и замены:
import fileinput import sys
defreplaceAll(file,searchExp,replaceExp): for line in fileinput.input(file, inplace=1): if searchExp in line: line = line.replace(searchExp,replaceExp) sys.stdout.write(line)
# Does a list of files, and # redirects STDOUT to the file in question for line in fileinput.input(files, inplace = 1): print line.replace("foo", "bar"),