我有以下代码:
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”,即我有旧内容后跟新的“替换”内容。我该怎么做才能删除旧的东西,只保留新的?
data = file.read()
。您的意思不是“无需先阅读就盲目地覆盖它”。
在写入之前您需要 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))
truncate
和 open(..., 'w')
都不会更改文件的 inode 编号(我测试了两次,一次使用 Ubuntu 12.04 NFS,一次使用 ext4)。
顺便说一句,这与 Python 并没有真正的关系。解释器调用相应的低级 API。方法 truncate()
在 C 编程语言中的工作方式相同:参见 http://man7.org/linux/man-pages/man2/truncate.2.html
file='path/test.xml'
with open(file, 'w') as filetowrite:
filetowrite.write('new content')
以“w”模式打开文件,您将能够用新内容替换其当前文本保存文件。
使用 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()
seek
和 truncate
!!!我无法弄清楚为什么单独使用 seek
不起作用。
write
负责从 cursor 位置写入文件。 write 不关心写入文件后是否有任何内容。 truncate
在此处执行从文件的 光标 位置删除其余内容的工作。
with open(...) as f: f.truncate() f.write(...)
(没有 seek(0)
),它似乎确实替换了文件内容。
file.seek(0)
才能正常工作。
See from How to Replace String in File 以一种简单的方式工作,并且是一个适用于 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()
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
我有一个类似的问题,而不是使用不同的“模式”覆盖我现有的文件,我只是在再次使用它之前删除了该文件,这样就好像我在每次运行我的代码时都附加到一个新文件.
使用 python3 pathlib 库:
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))
Neither truncate nor open(..., 'w') will change the inode number of the file
为什么它很重要?