web-dev-qa-db-ja.com

Python追加ではなく置換および上書き

私は次のコードを持っています:

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」が追加されます。つまり、古いコンテンツに新しい「置換」コンテンツが続いています。古いものを削除し、新しいものだけを保持するにはどうすればよいですか?

54
Kaly

書き込みの前にファイルの先頭に 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()

もう1つの方法は、ファイルを読み取ってから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))

truncateopen(..., 'w')もファイルの inode 番号を変更しません(Ubuntu 12.04 NFSで1回、ext4で1回、2回テストしました)。

ところで、これは実際にはPythonとは関係ありません。インタープリターは、対応する低レベルAPIを呼び出します。メソッドtruncate()は、Cプログラミング言語でも同じように機能します。 http://man7.org/linux/man-pages/man2/truncate.2.html を参照してください

62
guettli

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()
13
serv-inc
file='path/test.xml' 
with open(file, 'w') as filetowrite:
    filetowrite.write('new content')

ファイルを「w」モードで開きます。現在のテキストを置き換えて、ファイルを新しい内容に保存できます。

7
Chikku Jacob
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

同様の問題があり、異なる「モード」を使用して既存のファイルを上書きする代わりに、ファイルを削除してから再度使用するため、コードを実行するたびに新しいファイルに追加するようになります。

1
Nadia Salgado