Tengo el siguiente código:
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()
donde me gustaría reemplazar el contenido antiguo que está en el archivo con el nuevo contenido. Sin embargo, cuando ejecuto mi código, se agrega el archivo "test.xml", es decir, tengo el contenido antiguo seguido del nuevo contenido "reemplazado". ¿Qué puedo hacer para eliminar las cosas antiguas y conservar solo las nuevas?
data = file.read()
. No quiere decir "sobrescribirlo a ciegas sin necesidad de leerlo primero".Respuestas:
Necesita
seek
al principio del archivo antes de escribir y luego usarfile.truncate()
si desea reemplazarlo en el lugar: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()
La otra forma es leer el archivo y luego abrirlo nuevamente con
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))
Ni
truncate
tampocoopen(..., 'w')
cambiará el número de inodo del archivo (lo probé dos veces, una con Ubuntu 12.04 NFS y otra con ext4).Por cierto, esto no está realmente relacionado con Python. El intérprete llama a la API de bajo nivel correspondiente. El método
truncate()
funciona igual en el lenguaje de programación C: Ver http://man7.org/linux/man-pages/man2/truncate.2.htmlfuente
Neither truncate nor open(..., 'w') will change the inode number of the file
¿Por qué es importante?file='path/test.xml' with open(file, 'w') as filetowrite: filetowrite.write('new content')
Abra el archivo en modo 'w', podrá reemplazar su texto actual y guardar el archivo con contenido nuevo.
fuente
Usando
truncate()
, la solución podría serimport 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()
fuente
seek
ytruncate
!!! No podía entender por quéseek
no funcionaba solo.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
Tuve un problema similar, y en lugar de sobrescribir mi archivo existente usando los diferentes 'modos', simplemente eliminé el archivo antes de usarlo nuevamente, de modo que sería como si estuviera agregando un nuevo archivo en cada ejecución de mi código .
fuente
Consulte Cómo reemplazar cadena en archivo funciona de una manera simple y es una respuesta que funciona con
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()
fuente
Usando la biblioteca pathlib de python3 :
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))
Método similar que utiliza un enfoque diferente para las copias de seguridad:
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))
fuente