3 Stimmen

Zeichenketten in einer Textdatei an einer bestimmten Stelle aktualisieren

Ich würde gerne eine bessere Lösung finden, um die folgenden drei Schritte zu erreichen:

  1. Zeichenketten in einer bestimmten Zeile lesen
  2. Zeichenketten aktualisieren
  3. die aktualisierten Zeichenketten zurückschreiben

Unten sind meine Code, der funktioniert, aber ich frage mich, gibt es eine bessere (einfache) Lösungen?

new='99999'

f=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP','r+')
lines=f.readlines()
#the row number we want to update is given, so just load the content
x = lines[95]
print(x)
f.close()

#replace
f1=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP')
con = f1.read()
print con
con1 = con.replace(x[2:8],new) #only certain columns in this row needs to be updated
print con1
f1.close()

#write
f2 = open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'w')
f2.write(con1)
f2.close()

Danke! UPDATE: erhalten eine Idee von jtmoulia diesmal wird es einfacher

def replace_line(file_name, line_num, col_s, col_e, text):
    lines = open(file_name, 'r').readlines()
    temp=lines[line_num]
    temp = temp.replace(temp[col_s:col_e],text)
    lines[line_num]=temp
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()

3voto

C2H5OH Punkte 5271

Das Problem bei Textdaten, selbst wenn sie in Tabellenform vorliegen, ist, dass die Byte-Offsets nicht vorhersehbar sind. Bei der Darstellung von Zahlen mit Zeichenketten hat man beispielsweise ein Byte pro Ziffer, während man bei der Verwendung des Binärsystems (z. B. Zweierkomplement) immer vier oder acht Bytes für kleine und große ganze Zahlen benötigt.

Wenn Ihr Textformat jedoch so streng ist, dass Sie mit dem Ersetzen von Bytes auskommen können, ohne die Größe der Datei zu verändern, können Sie versuchen, die Funktion Standard mmap Modul . Mit dieser Funktion können Sie eine Datei als änderbar Byte-String und ändern Sie Teile davon an Ort und Stelle und lassen Sie den Kernel das Speichern der Datei für Sie übernehmen.

Andernfalls ist jede der anderen Antworten viel besser für das Problem geeignet.

1voto

jtmoulia Punkte 660

Zunächst einmal müssen Sie die Datei nicht jedes Mal neu öffnen und einlesen. Die r+ Modus können Sie die angegebene Datei lesen und schreiben.

Vielleicht etwas wie

with open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'r+') as f:
    lines = f.readlines()
    #... Perform whatever replacement you'd like on lines
    f.seek(0)
    f.writelines(lines)

Auch, Bearbeiten einer bestimmten Zeile in einer Textdatei in Python

0voto

Chuck Kollars Punkte 2035

Als ich etwas Ähnliches machen musste (für eine Webmin-Anpassung), habe ich es komplett in PERL gemacht, weil das Webmin-Framework das verwendet, und ich fand es ziemlich einfach. Ich nehme an (bin mir aber nicht sicher), dass es in Python etwas Vergleichbares gibt. Lesen Sie zuerst die gesamte Datei auf einmal in den Speicher zu speichern (die PERL-Methode, dies zu tun, wird wahrscheinlich "slurp" genannt). (Die Idee, die gesamte Datei im Speicher zu halten und nicht nur eine Zeile, machte früher wenig Sinn {oder war sogar unmöglich}. Aber heutzutage ist der Arbeitsspeicher so groß, dass es der einzige Weg ist). Verwenden Sie dann die split Operator, um die Datei in Zeilen zu unterteilen und jede Zeile in ein anderes Element eines riesigen Arrays zu schreiben. Sie können dann die gewünschte Zeilennummer als Index in dem Array verwenden (denken Sie daran, dass Array-Indizes normalerweise mit 0 beginnen). Schließlich ändern Sie den Zeilentext mit Hilfe von "regulären Ausdrücken". Ändern Sie dann eine weitere Zeile, und noch eine, und noch eine (oder nehmen Sie eine weitere Änderung in derselben Zeile vor). Wenn Sie damit fertig sind, verwenden Sie join um alle Zeilen des Arrays wieder zu einer einzigen großen Zeichenkette zusammenzufügen. Schreiben Sie dann die gesamte geänderte Datei heraus.

Ich habe zwar nicht den vollständigen Code zur Hand, aber hier ist ein ungefähres Fragment eines Teils des PERL-Codes, damit Sie sehen können, was ich meine:

our @filelines = ();
our $lineno = 43;
our $oldstring = 'foobar';
our $newstring = 'fee fie fo fum';
$filelines[$lineno-1] =~ s/$oldstring/$newstring/ig; 
# "ig" modifiers for case-insensitivity and possible multiple occurences in the line
# use different modifiers at the end of the s/// construct as needed

-1voto

guidoism Punkte 7332
FILENAME = 'C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP'
lines = list(open(FILENAME))
lines[95][2:8] = '99999'
open(FILENAME, 'w').write(''.join(lines))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X