Python解析后重写文件

2024-10-01 13:41:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,我需要做一个解析练习。我得到了一个文件,我需要解析它(只是头文件),但在这个过程之后,我需要保持文件的格式、扩展名和磁盘中的相同位置,但只保留新文件头的不同。。在

我试过这个密码。。。在

for line in open ('/home/name/db/str/dir/numbers/str.phy'):
    if line.startswith('ENS'):
        linepars = re.sub ('ENS([A-Z]+)0+([0-9]{6})','\\1\\2',line)
        print linepars

…它完成了任务,但我不知道如何用新的解析“覆盖”文件。在


Tags: 文件in密码homefor头文件过程格式
3条回答

正如其他人在这里说的,您希望打开一个文件并使用该文件对象的.write()方法。在

最好的方法是打开另一个文件进行写入:

import os

current_cfg = open(...)
parsed_cfg  = open(..., 'w')
for line in current_cfg:
    new_line = parse(line)
    print new_line
    parsed.cfg.write(new_line + '\n')
current_cfg.close()
parsed_cfg.close()

os.rename(....) # Rename old file to backup name
os.rename(....) # Rename new file into place

另外,我建议查看tempfile模块,并使用其中一种方法命名新文件或打开/创建它。个人而言,我希望将新文件放在与现有文件相同的目录中,以确保os.rename以原子方式工作(名为的配置文件将保证指向旧文件或新文件;在任何情况下,它都不会指向部分写入/复制的文件)。在

最简单的方法,但不是最有效的(到目前为止,尤其是对于长文件)是重写整个文件。在

您可以通过打开第二个文件句柄并重写每一行来实现这一点,但在头的情况下,您需要编写已解析的头。例如

fr = open('/home/name/db/str/dir/numbers/str.phy')
fw = open('/home/name/db/str/dir/numbers/str.phy.parsed', 'w') # Name this whatever makes sense

for line in fr:
    if line.startswith('ENS'):
        linepars = re.sub ('ENS([A-Z]+)0+([0-9]{6})','\\1\\2',line)
        fw.write(linepars)
    else:
        fw.write(line)

fw.close()
fr.close()

EDIT:注意,这不使用readlines(),因此它的内存效率更高。它也不存储每个输出行,但一次只存储一行,立即将其写入文件。在

作为一个很酷的技巧,您可以在输入文件上使用with语句来避免必须关闭它(Python2.5+):

^{pr2}$

欢迎光临:-)

下面的代码完成了这项工作。
我的意思是它确实覆盖了自己的文件;这正是OP所要求的。这是可能的,因为转换只是删除字符,所以文件的指针fo写总是在文件指针fi的后面。在

import re

regx = re.compile('\AENS([A-Z]+)0+([0-9]{6})')

with open('bomo.phy','rb+') as fi, open('bomo.phy','rb+') as fo:
    fo.writelines(regx.sub('\\1\\2',line) for line in fi)

我认为写操作系统不是一次写一行,而是通过一个缓冲区。因此,在写入一组转换后的行之前,需要先读取几行。我就是这么想的。在

相关问题 更多 >