У меня такой код:
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источник
Neither truncate nor open(..., 'w') will change the inode number of the file
почему это важно?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
один не работал.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()
источник
Использование библиотеки pathlib 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))
Аналогичный метод с использованием другого подхода к резервному копированию:
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))
источник