【问题标题】:How can I alter a file and write only the changes to disk - basically, sed (python)?如何更改文件并仅将更改写入磁盘 - 基本上是 sed (python)?
【发布时间】:2011-03-11 19:48:16
【问题描述】:

假设我有一个文件 /etc/conf1

它的内容类似于

option = banana
name = monkey
operation = eat

假设我想用“鸵鸟”替换“猴子”。如果不将文件读入内存,更改它然后将其全部写回,我怎么能做到这一点?基本上,我怎样才能“就地”修改文件?

【问题讨论】:

  • 有困难。您认为通过修改“就地”可以实现什么?它是一个大文件,您担心将其保存在内存中吗?
  • 如果您想更改文件大小,我认为您不能。 sed 也不能这样做,当前的操作系统根本不支持它。作为替代方案,您可以查看 ConfigParser 模块以解析 INI 样式的配置文件。
  • 在当前情况下,它更像是一个假设的“我读取文件、修改文件、写入文件并在中途遇到问题并最终导致文件损坏的可能性有多大?”问题。我想过一种“读取 conf1,修改,写入 conf1.temp,mv conf1.temp conf1”的方法,但我认为可以有一种更优雅的方式来做到这一点。就地模式会很酷。

标签: python file sed fopen file-manipulation


【解决方案1】:

你应该看看文件输入模块:

http://docs.python.org/library/fileinput.html

有一个选项可以通过输入法进行就地编辑:

http://docs.python.org/library/fileinput.html#fileinput.input

更新 - 示例代码:

import fileinput import re import sys for line in fileinput.input(inplace=True): sys.stdout.write(re.sub(r'monkey', 'ostrich', line))

使用 sys.stdout.write 以免在其中添加任何额外的换行符。

【讨论】:

  • 试过了,无法正常工作。 fileinput 存在的事实是我提出这个问题的原因。你能详细说明或提供一个例子吗?
  • 我现在添加了一些示例代码。注意它在技术上确实将文件读入内存(一次一行),但这相当于 sed 的操作方式。关键是即使没有更改,也必须输出该行。
【解决方案2】:

sed -i.bak '/monkey$/newword/' file

【讨论】:

  • ... 在 python 中,没有 sed、subprocess、os.system 等:D
【解决方案3】:

仅当您不更改文件大小或仅追加文件时,就地修改很容易。以下示例将文件的第一个字节替换为“a”字符:

fd = os.open("...", os.O_WRONLY | os.O_CREAT)
os.write(fd, "a")
os.close(fd)

请注意,Python 的 file 对象不支持这一点,您必须使用低级函数。要追加,请在"a" 模式下使用open() 函数打开文件文件。

【讨论】:

  • fp= open("…", "r+b"); fp.write("a"); fp.close() 现在,当你说“Python 的 file 对象不支持这个”时,我是不是误会了你?
【解决方案4】:

CPU 指令对来自内存的数据进行操作。

您要读取的文件部分必须先驻留在内存中,然后才能读取;在将任何内容写入磁盘之前,该信息必须在内存中。

整个文件不必一次在那里,但要对整个文件进行搜索替换,文件的每个字符都会在某个时候通过 RAM。 p>

您可能正在寻找类似 mmap() 系统调用的东西。上面的 fileinput 模块听起来很合理。

【讨论】:

  • 如果你只是解析直到你达到你想要的配置选项,你只会在最坏的情况下读取整个文件。我猜我的问题与移动文件的内容有关...
【解决方案5】:

这取决于您所说的“就地”是什么意思。如果你想用supercalifragilisticexpialidocious 替换monkey 怎么办?是否要覆盖剩余的文件?如果没有,您将不得不提前阅读并将文件的后续内容向前移动。

【讨论】:

  • 我认为,在资源方面,转移比直接编写新文件更昂贵?
【解决方案6】:

你不能。 “ostrich”比“monkey”多一个字母,所以至少从那时起你必须重写文件。文件系统不支持向上或向下“移动”文件内容。

如果只是一个小文件,那也没必要去操心,还不如重写整个文件。

如果文件非常大,您需要重新考虑文件内容的内部设计,例如,使用基于块的方法。

【讨论】:

  • 这是困扰我一段时间的事情,我永远无法弄清楚如何做到这一点。我只是觉得我在处理文件方面很烂。实际上,我曾经在 python 中实现过“读取块,修改,写入块”方法,并被告知这是一件愚蠢的事情,因为当你 f.read() 时,系统实际上只加载了几个块时间......是的,这是一个很大(100MB 大)的文件。
猜你喜欢
  • 2012-04-13
  • 1970-01-01
  • 2012-03-09
  • 2017-02-14
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
相关资源
最近更新 更多