Вопрос-Ответ

Search and replace a line in a file in Python

Поиск и замена строки в файле на Python

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

Каков наилучший способ сделать это в следующем коде?

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

Здесь происходит следующее:


  1. Исходный файл перемещается в файл резервной копии

  2. Стандартный вывод перенаправляется в исходный файл внутри цикла

  3. Таким образом, любые print инструкции записывают обратно в исходный файл

fileinput имеет больше наворотов. Например, его можно использовать для автоматической работы со всеми файлами в sys.args[1:], без необходимости перебирать их явно. Начиная с Python 3.2, он также предоставляет удобный контекстный менеджер для использования в with инструкции.


Хотя fileinput отлично подходит для одноразовых скриптов, я бы поостерегся использовать его в реальном коде, потому что, по общему признанию, он не очень удобочитаем или знаком. В реальном (производственном) коде стоит потратить еще несколько строк кода, чтобы сделать процесс явным и, таким образом, сделать код читабельным.

Есть два варианта:


  1. Файл не слишком большой, и вы можете просто прочитать его полностью в памяти. Затем закройте файл, снова откройте его в режиме записи и запишите измененное содержимое обратно.

  2. Файл слишком велик, чтобы его можно было сохранить в памяти; вы можете переместить его во временный файл и открыть его, читая построчно и записывая обратно в исходный файл. Обратите внимание, что для этого требуется вдвое больший объем памяти.

Ответ 2

Я предполагаю, что это должно быть сделано чем-то вроде этого. В основном это записывает содержимое в новый файл и заменяет старый файл новым файлом:

from tempfile import mkstemp
from shutil import move, copymode
from os import fdopen, remove

def replace(file_path, pattern, subst):
#Create temp file
fh, abs_path = mkstemp()
with fdopen(fh,'w') as new_file:
with open(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

def replaceAll(file,searchExp,replaceExp):
for line in fileinput.input(file, inplace=1):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
sys.stdout.write(line)

Пример использования:

replaceAll("/fooBar.txt","Hello\sWorld!$","Goodbye\sWorld.")
Ответ 4

Это должно сработать: (редактирование на месте)

import fileinput

# 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"),
2023-08-18 05:33 python file