在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
13 个回答
99
这里有另一个经过测试的例子,它可以匹配搜索和替换的模式:
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.")
309
最简单的方法可能就是使用 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
对于临时脚本来说很不错,但我会对在正式代码中使用它有所保留,因为它的可读性和熟悉度确实不高。在实际的(生产)代码中,花几行代码让过程变得明确,这样代码会更容易理解。
有两种选择:
- 如果文件不大,你可以把它全部读入内存。然后关闭文件,重新以写入模式打开它,把修改后的内容写回去。
- 如果文件太大,无法全部存入内存,你可以把它移动到一个临时文件中,逐行读取,然后写回到原始文件中。注意,这样需要两倍的存储空间。
235
我想这样的代码应该可以做到。它的基本功能是把内容写入一个新文件,然后用这个新文件替换掉旧文件:
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)