Vervangen en overschrijven in plaats van toevoegen

Ik heb de volgende 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()

waar ik de oude inhoud in het bestand wil vervangen door de nieuwe inhoud. Wanneer ik echter mijn code uitvoer, wordt het bestand “test.xml” toegevoegd, d.w.z. ik heb de oude inhoud gevolgd door de nieuwe “vervangen” inhoud. Wat kan ik doen om de oude dingen te verwijderen en alleen de nieuwe te behouden?


Antwoord 1, autoriteit 100%

Je moet seeknaar het begin van het bestand voordat u gaat schrijven en gebruik vervolgens file.truncate()als u ter plaatse wilt vervangen:

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()

De andere manier is om het bestand te lezen en het vervolgens opnieuw te openen met 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))

Noch truncatenoch open(..., 'w')veranderen de inode-nummer van het bestand (ik heb twee keer getest, één keer met Ubuntu 12.04 NFS en één keer met ext4).

Trouwens, dit heeft niet echt met Python te maken. De tolk roept de bijbehorende low-level API aan. De methode truncate()werkt hetzelfde in de programmeertaal C: Zie http://man7.org/linux/man-pages/man2/truncate.2.html


Antwoord 2, autoriteit 65%

file='path/test.xml' 
with open(file, 'w') as filetowrite:
    filetowrite.write('new content')

Open het bestand in ‘w’-modus, u kunt de huidige tekst vervangen en het bestand opslaan met nieuwe inhoud.


Antwoord 3, autoriteit 12%

Met truncate()zou de oplossing kunnen zijn

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()

Antwoord 4, autoriteit 2%

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

Ik had een soortgelijk probleem en in plaats van mijn bestaande bestand te overschrijven met behulp van de verschillende ‘modi’, heb ik het bestand verwijderd voordat ik het opnieuw gebruikte, zodat het zou zijn alsof ik bij elke run een nieuw bestand aan het toevoegen was van mijn code.


Antwoord 5

Zie van Hoe een string in een bestand te vervangenwerkt in een eenvoudige manier en is een antwoord dat werkt met 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()

Antwoord 6

Python3 pathlib-bibliotheek gebruiken:

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))

Vergelijkbare methode met verschillende benadering van back-ups:

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))

Other episodes