在Python中搜索并替换文件中的一行

2024-04-25 13:57:48 发布

您现在位置: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

Tags: 文件to方法内存代码in内容for
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.")

最短的方法可能是使用fileinput module。例如,下面将行号添加到文件中:

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. 该文件太大,无法存储在内存中;您可以将其移到临时文件中,然后打开该文件,逐行读取,再写入原始文件。请注意,这需要两倍的存储空间。

我想应该是这样的。它基本上将内容写入新文件,并用新文件替换旧文件:

from tempfile import mkstemp
from shutil import move
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))
    #Remove original file
    remove(file_path)
    #Move new file
    move(abs_path, file_path)

相关问题 更多 >

    热门问题