替换并覆盖,而不是追加

我有以下密码:

import re
#open the xml file for reading:
file = open('path/test.xml','r+')
#convert to string:
data = file.read()
file.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>",r"<xyz>ABC</xyz>\1<xyz>\2</xyz>",data))
file.close()

我想用新内容替换文件中的旧内容。但是,当我执行代码时,文件“ test.xml”被附加,也就是说,旧的内容后面跟着新的“替换”内容。我该怎么做才能删除旧的东西,只保留新的?

423749 次浏览

在写文件之前,你需要把 seek写到文件的开头,如果你想替换的话,可以使用 file.truncate():

import re


myfile = "path/test.xml"


with open(myfile, "r+") as f:
data = f.read()
f.seek(0)
f.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>", r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", data))
f.truncate()

另一种方法是读取文件,然后用 open(myfile, 'w')再次打开它:

with open(myfile, "r") as f:
data = f.read()


with open(myfile, "w") as f:
f.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>", r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", data))

truncateopen(..., 'w')都不会改变文件的 Inode编号(我测试了两次,一次使用 Ubuntu 12.04 NFS,一次使用 ext4)。

顺便说一下,这与 Python 并无实际关系。解释器调用相应的低级 API。方法 truncate()在 C 编程语言中的工作原理是相同的: 参见 http://man7.org/linux/man-pages/man2/truncate.2.html

使用 truncate(),解决方案可以是

import re
#open the xml file for reading:
with open('path/test.xml','r+') as f:
#convert to string:
data = f.read()
f.seek(0)
f.write(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>",r"<xyz>ABC</xyz>\1<xyz>\2</xyz>",data))
f.truncate()
file='path/test.xml'
with open(file, 'w') as filetowrite:
filetowrite.write('new content')

以“ w”模式打开文件,您将能够用新内容替换当前保存文件的文本。

import os#must import this library
if os.path.exists('TwitterDB.csv'):
os.remove('TwitterDB.csv') #this deletes the file
else:
print("The file does not exist")#add this to prevent errors

我也遇到过类似的问题,我没有使用不同的“模式”覆盖我现有的文件,而是在再次使用之前删除了它,这样就好像我在每次运行代码时都要添加一个新的文件。

如何替换文件中的字符串中看到的工作原理很简单,是一个与 replace一起工作的答案

fin = open("data.txt", "rt")
fout = open("out.txt", "wt")


for line in fin:
fout.write(line.replace('pyton', 'python'))


fin.close()
fout.close()

使用 python3Pathlib库:

import re
from pathlib import Path
import shutil


shutil.copy2("/tmp/test.xml", "/tmp/test.xml.bak") # create backup
filepath = Path("/tmp/test.xml")
content = filepath.read_text()
filepath.write_text(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>",r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", content))

使用不同备份方法的类似方法:

from pathlib import Path


filepath = Path("/tmp/test.xml")
filepath.rename(filepath.with_suffix('.bak')) # different approach to backups
content = filepath.read_text()
filepath.write_text(re.sub(r"<string>ABC</string>(\s+)<string>(.*)</string>",r"<xyz>ABC</xyz>\1<xyz>\2</xyz>", content))

在我的例子中,下面的代码起到了作用

with open("output.json", "w+") as outfile:  #using w+ mode to create file if it not exists. and overwrite the existing content
json.dump(result_plot, outfile)