在 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

原文由 pkit 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 277
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)

原文由 Thomas Watnedal 发布,翻译遵循 CC BY-SA 4.0 许可协议

最短的方法可能是使用 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. 文件太大,无法存储在内存中;您可以将其移至临时文件并打开它,逐行读取,然后写回原始文件。请注意,这需要两倍的存储空间。

原文由 Eli Bendersky 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题