Ich habe folgenden Code:
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()
Hier möchte ich den alten Inhalt in der Datei durch den neuen Inhalt ersetzen. Wenn ich jedoch meinen Code ausführe, wird die Datei "test.xml" angehängt, dh ich habe den alten Inhalt gefolgt vom neuen "ersetzten" Inhalt. Was kann ich tun, um das alte Zeug zu löschen und nur das neue zu behalten?
data = file.read()
. Sie meinen nicht "blind überschreiben, ohne es zuerst lesen zu müssen".Antworten:
Sie müssen
seek
vor dem Schreiben an den Anfang der Datei gehen und diese dann verwenden,file.truncate()
wenn Sie Folgendes ersetzen möchten: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()
Die andere Möglichkeit besteht darin, die Datei zu lesen und sie dann erneut zu öffnen mit
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))
Weder
truncate
nochopen(..., 'w')
wird die Inode- Nummer der Datei geändert (ich habe zweimal getestet, einmal mit Ubuntu 12.04 NFS und einmal mit ext4).Dies hängt übrigens nicht wirklich mit Python zusammen. Der Interpreter ruft die entsprechende Low-Level-API auf. Die Methode
truncate()
funktioniert in der Programmiersprache C genauso: Siehe http://man7.org/linux/man-pages/man2/truncate.2.htmlquelle
Neither truncate nor open(..., 'w') will change the inode number of the file
warum ist es wichtigfile='path/test.xml' with open(file, 'w') as filetowrite: filetowrite.write('new content')
Öffnen Sie die Datei im 'w'-Modus. Sie können den aktuellen Text ersetzen und die Datei durch neuen Inhalt speichern.
quelle
Mit
truncate()
könnte die Lösung seinimport 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()
quelle
seek
undtruncate
!!! Ich konnte nicht herausfinden, warumseek
allein nicht funktionierte.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
Ich hatte ein ähnliches Problem und anstatt meine vorhandene Datei mit den verschiedenen "Modi" zu überschreiben, habe ich die Datei einfach gelöscht, bevor ich sie erneut verwendete, so dass es so war, als würde ich bei jedem Durchlauf meines Codes an eine neue Datei anhängen .
quelle
Siehe Ersetzen von Zeichenfolgen in Dateien funktioniert auf einfache Weise und ist eine Antwort, die funktioniert
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()
quelle
Verwenden der Python3- Pathlib- Bibliothek:
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))
Ähnliche Methode mit unterschiedlichem Ansatz für Backups:
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))
quelle