可以在文件中就地修改行吗?

84 投票
5 回答
73041 浏览
提问于 2025-04-16 14:32

有没有办法逐行读取一个文件,并在读取的过程中直接修改某一行的内容呢?

5 个回答

10

不可以。你不能安全地同时对一个文件进行读取和写入,因为你对文件所做的任何修改可能会覆盖你还没有读取的内容。要安全地操作这个文件,你需要先把文件的内容读到一个缓冲区中,必要时更新其中的某些行,然后再把整个文件写回去。

如果你是逐字逐字地替换文件中的内容(也就是说,你替换的文本和新文本的长度是一样的),那么这样做是可以的,但这就像是引发了一场麻烦,所以我建议你还是直接把整个文件读出来,在内存中替换内容(或者通过一个临时文件),然后再写回去。

32

fileinput模块的接口设计得很糟糕,我找到一个更好用的模块来完成这个任务,叫做 in_place,下面是Python 3的示例:

import in_place

with in_place.InPlace('data.txt') as file:
    for line in file:
        line = line.replace('test', 'testZ')
        file.write(line)
    file.close()

fileinput的主要区别:

  • 它不是直接修改sys.stdout,而是返回一个新的文件句柄供你写入。
  • 这个文件句柄支持所有标准的输入输出方法,而不仅仅是readline()

重要提示

  1. 如果你不使用file.write()来重新写入文件,这个解决方案会删除文件中的每一行。
  2. 另外,如果处理过程被中断,你会丢失任何尚未重新写入的文件行。
61

能不能逐行读取一个文件,并在读取的同时直接修改某一行呢?

可以通过使用一个备份文件来模拟这个过程,就像Python标准库中的 fileinput 模块 所做的那样。

下面是一个示例脚本,它会从命令行或 stdin 中给出的文件中删除不满足 some_condition 的行:

#!/usr/bin/env python
# grep_some_condition.py
import fileinput

for line in fileinput.input(inplace=True, backup='.bak'):
    if some_condition(line):
        print line, # this goes to the current file

示例:

$ python grep_some_condition.py first_file.txt second_file.txt

完成后,first_file.txtsecond_file.txt 文件中只会保留满足 some_condition() 条件的行。

撰写回答