Я хочу перебрать содержимое текстового файла, выполнить поиск и замену в некоторых строках и записать результат обратно в файл. Я мог бы сначала загрузить весь файл в память, а затем записать его обратно, но это, вероятно, не лучший способ сделать это.
Каков наилучший способ сделать это в следующем коде?
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
file
скрывает предопределенный класс с тем же именем.mkstemp()
возвращается 2-кортеж, и(fh, abs_path) = fh, abs_path
я не знал этого, когда задавал вопрос.Самый короткий путь, вероятно, будет использовать модуль fileinput . Например, следующий код добавляет номера строк в файл на месте:
Что происходит здесь:
print
заявления записывают обратно в исходный файлfileinput
имеет больше наворотов. Например, его можно использовать для автоматической работы со всеми файламиsys.args[1:]
, без необходимости явной итерации по ним. Начиная с Python 3.2, он также предоставляет удобный контекстный менеджер для использования вwith
выражении.Хотя
fileinput
это отлично подходит для одноразовых скриптов, я бы с осторожностью использовал его в реальном коде, потому что, по общему признанию, он не очень читабелен или знаком. В реальном (производственном) коде стоит потратить всего несколько строк кода, чтобы сделать процесс явным и, следовательно, сделать код читабельным.Есть два варианта:
источник
print(line, end='')
Вот еще один пример, который был протестирован и будет соответствовать шаблонам поиска и замены:
Пример использования:
источник
searchExp in line
ниline.replace
операциями с регулярными выражениями. Конечно, пример использования неверен.if searchExp in line: line = line.replace(searchExp, replaceExpr)
тебя можно просто написатьline = line.replace(searchExp, replaceExpr)
. Исключение не генерируется, строка просто остается неизменной.sys.stdout.write(line)
. Еще раз спасибо!Это должно работать: (редактирование на месте)
источник
files
должна быть строка, содержащая имя файла, а не объект файла .Основано на ответе Томаса Ватнедала. Тем не менее, это не дает точного ответа на прямую часть исходного вопроса. Функция все еще может заменять построчно
Эта реализация заменяет содержимое файла без использования временных файлов, в результате чего права доступа к файлам остаются неизменными.
Также re.sub вместо replace разрешает замену регулярных выражений вместо замены обычного текста.
Чтение файла в виде одной строки вместо строки за строкой позволяет выполнять многострочное сопоставление и замену.
источник
rb
иwb
атрибуты при открытии файлов, так как это сохранит исходные окончания строкКак подсказывает lassevk, запишите новый файл по ходу работы, вот пример кода:
источник
Если вам нужна универсальная функция, которая заменяет любой текст другим текстом, это, вероятно, лучший способ, особенно если вы поклонник регулярных выражений:
источник
Более питоническим способом было бы использовать контекстные менеджеры, подобные приведенному ниже коду:
Вы можете найти полный фрагмент здесь .
источник
Создайте новый файл, скопируйте строки из старого в новый и выполните замену, прежде чем записывать строки в новый файл.
источник
Расширяя ответ @ Kiran, который, я согласен, является более лаконичным и Pythonic, он добавляет кодеки для поддержки чтения и записи UTF-8:
источник
Используя ответ hamishmcn в качестве шаблона, я смог найти в файле строку, соответствующую моему регулярному выражению, и заменить ее пустой строкой.
источник
fileinput
довольно просто, как упоминалось в предыдущих ответах:Объяснение:
fileinput
Я могу принять несколько файлов, но я предпочитаю закрывать каждый файл сразу после его обработки. Так размещен синглfile_path
вwith
заявленииprint
оператор не печатает ничего когдаinplace=True
, потомуSTDOUT
что пересылается в исходный файл.end=''
Вprint
заявлении стоит исключить промежуточные пустые новые строки.Может использоваться следующим образом:
источник
если вы удалите отступ, как показано ниже, он будет искать и заменять в несколько строк. Смотрите ниже, например.
источник