Ich möchte den Inhalt einer Textdatei durchlaufen und in einigen Zeilen suchen und ersetzen und das Ergebnis in die Datei zurückschreiben. Ich könnte zuerst die gesamte Datei in den Speicher laden und dann zurückschreiben, aber das ist wahrscheinlich nicht der beste Weg, dies zu tun.
Was ist der beste Weg, dies im folgenden Code zu tun?
f = open(file)
for line in f:
if line.contains('foo'):
newline = line.replace('foo', 'bar')
# how to write this newline back to the file
file
Beschattet vordefinierte Klasse mit dem gleichen Namen.mkstemp()
ein 2-Tupel zurückgegeben wird, und(fh, abs_path) = fh, abs_path
das wusste ich nicht, als ich die Frage stellte.Der kürzeste Weg wäre wahrscheinlich die Verwendung des Dateieingabemoduls . Im Folgenden werden beispielsweise Zeilennummern direkt zu einer Datei hinzugefügt:
Was hier passiert ist:
print
schreiben alle Anweisungen zurück in die Originaldateifileinput
hat mehr Schnickschnack. Beispielsweise können Sie damit automatisch alle Dateien insys.args[1:]
bearbeiten, ohne dass Sie diese explizit durchlaufen müssen. Ab Python 3.2 bietet es auch einen praktischen Kontextmanager zur Verwendung in einerwith
Anweisung.Obwohl
fileinput
es sich hervorragend für Wegwerfskripte eignet, würde ich es nicht in echtem Code verwenden, da es zugegebenermaßen nicht sehr lesbar oder vertraut ist. In echtem (Produktions-) Code lohnt es sich, nur noch ein paar Zeilen Code auszugeben, um den Prozess explizit und damit lesbar zu machen.Es gibt zwei Möglichkeiten:
quelle
print(line, end='')
Hier ist ein weiteres Beispiel, das getestet wurde und mit Such- und Ersetzungsmustern übereinstimmt:
Anwendungsbeispiel:
quelle
searchExp in line
nochline.replace
reguläre Ausdrücke. Sicher ist die Beispielverwendung falsch.if searchExp in line: line = line.replace(searchExp, replaceExpr)
kannst du einfach schreibenline = line.replace(searchExp, replaceExpr)
. Es wird keine Ausnahme generiert, die Zeile bleibt einfach unverändert.sys.stdout.write(line)
. Danke noch einmal!Dies sollte funktionieren: (Inplace-Bearbeitung)
quelle
files
dies eine Zeichenfolge sein sollte, die den Dateinamen enthält, kein Dateiobjekt .Basierend auf der Antwort von Thomas Watnedal. Dies beantwortet jedoch nicht den zeilenweisen Teil der ursprünglichen Frage genau. Die Funktion kann weiterhin von Zeile zu Zeile ersetzt werden
Diese Implementierung ersetzt den Dateiinhalt, ohne temporäre Dateien zu verwenden. Infolgedessen bleiben die Dateiberechtigungen unverändert.
Auch re.sub anstelle von replace ermöglicht das Ersetzen von Regex anstelle des Ersetzens nur von einfachem Text.
Das Lesen der Datei als einzelne Zeichenfolge anstelle von Zeile für Zeile ermöglicht eine mehrzeilige Übereinstimmung und Ersetzung.
quelle
rb
undwb
Attribute verwenden, da dadurch die ursprünglichen Zeilenenden erhalten bleibenWie lassevk vorschlägt, schreiben Sie die neue Datei währenddessen aus. Hier ist ein Beispielcode:
quelle
Wenn Sie eine generische Funktion wollen , sind die ersetzt jeden Text mit einem anderen Text, dann ist dies wahrscheinlich der beste Weg zu gehen, vor allem , wenn Sie ein Fan von regex ist sind:
quelle
Ein pythonischerer Weg wäre die Verwendung von Kontextmanagern wie dem folgenden Code:
Den vollständigen Ausschnitt finden Sie hier .
quelle
Erstellen Sie eine neue Datei, kopieren Sie die Zeilen von der alten in die neue und ersetzen Sie sie, bevor Sie die Zeilen in die neue Datei schreiben.
quelle
Wenn Sie die Antwort von @ Kiran erweitern, die meiner Meinung nach prägnanter und pythonischer ist, werden Codecs hinzugefügt, die das Lesen und Schreiben von UTF-8 unterstützen:
quelle
Mit der Antwort von hamishmcn als Vorlage konnte ich in einer Datei nach einer Zeile suchen, die meinem regulären Ausdruck entspricht, und sie durch eine leere Zeichenfolge ersetzen.
quelle
fileinput
ist ganz einfach, wie in früheren Antworten erwähnt:Erläuterung:
fileinput
kann mehrere Dateien akzeptieren, aber ich ziehe es vor, jede einzelne Datei zu schließen, sobald sie verarbeitet wird. Also einfachfile_path
inwith
Aussage gesetzt.print
Anweisung druckt nichts, wenninplace=True
, weilSTDOUT
an die Originaldatei weitergeleitet wird.end=''
inprint
Anweisung ist es, leere Zwischenzeilen zu entfernen.Kann wie folgt verwendet werden:
quelle
Wenn Sie den Einzug wie folgt entfernen, wird er in mehreren Zeilen gesucht und ersetzt. Siehe unten zum Beispiel.
quelle