Textdatei mittels Python ändern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 10:31

Hallo liebe Python-User.
Zunächst möchte ich mich für meine evtl etwas einfachen oder gar dummen Fragen entschuldigen. Ich nutze erst seit gerstern Python und bin in der Zwickmühle, dass mein Chef heut noch eine Lösung erwartet...
Meine Ziel ist es eine ganz bestimmte Zeile in einer Textdatei zu ändern bzw etas einzufügen. Leider weiß ich nicht, wie das in Python geht. Die append Option geht ja annähernd in die Richtung, nur das eben lediglich ans Ende der Datei geschrieben werden kann.
Mir wäre es lieb, wenn ich beispielsweise das Eingügen einer neuen Textzeile so steuern könnte, dass es immer nach einem bestimmten bereits vorhandenen Wort geschieht. Alternativ ginge auch das Einfügen in einer bestimmten Zeilennummer.
Ich hoffe ihr könnt mir evtl helfen.

Vielen Dank und beste Grüße.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 17. März 2010, 10:39

Hallo und willkommen im Forum!
nullstein hat geschrieben:Zunächst möchte ich mich für meine evtl etwas einfachen oder gar dummen Fragen entschuldigen.
Das mußt Du nicht - wir sind alle mal angefangen. Wir erwarten aber ein gewisses Maß an Mitarbeit ;-).
nullstein hat geschrieben:Ich nutze erst seit gerstern Python und bin in der Zwickmühle, dass mein Chef heut noch eine Lösung erwartet...
Sag´ ihm, daß das unrealistisch sein kann.
nullstein hat geschrieben:Meine Ziel ist es eine ganz bestimmte Zeile in einer Textdatei zu ändern bzw etas einzufügen. Leider weiß ich nicht, wie das in Python geht.
Zeig´ mal was Du bisher hast. Das gehört zwar zu den einfacheren Problemen, aber Du sollst dabei ja was lernen und außerdem ist das Problem ein bißchen unspezifisch beschrieben ...

Gruß,
Christian
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 10:47

Also ich habe bisher folgendes:

Code: Alles auswählen

...
 sdatei = open('datei.txt')
 l = sdatei.readlines()
 sdatei.close()
 l.append('Na funktioniert es?\n')
 sdatei = open('datei.txt','w')
 sdatei.write("".join(l))
 sdatei.close()
...
Problem ist, dass der Text Na funktioniert es? ans Ende gesetzt wird. Ich brauch den neuen Text aber an einer ganz bestimmten in meiner Datei. Zum Beispiel immer nach der Zeile mit dem Inhalt Schuhe:.
Alternativ ginge auch, dass ich den neuen Text immer in der 12. Zeile brauche.
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Mittwoch 17. März 2010, 11:02

Verwende anstelle von .append(value) .insert(index, value)
da bekommstu dann dein neues Element eingefügt.

Wenn du es nicht an einem Festen wert, sondern nach dem Wort Schuhe einfügen willst, verwendest du: liste.insert(liste.index('Schuhe')+1, value)

Sollte es mehrfach eingefügt werden, weil Schuhe mehrfach vor kommt, so schleife das irgendwie:

Code: Alles auswählen

i = liste.index('Schuhe')
while True:
    try:
        liste.insert(i+1, 'deinWert')
        i = liste.index('Schuhe', i+1)
    except ValueError:
        break
Ungetestet!
Zuletzt geändert von ... am Mittwoch 17. März 2010, 11:12, insgesamt 1-mal geändert.
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 11:10

SUPER!!!!! :D :D :D :D

Vielen Dank.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 17. März 2010, 11:12

Code: Alles auswählen

with open(filename) as f:
    lines = f.readlines()

lines.insert(0, "Erster!\n")

with open(filename + ".new", "w") as f:
    f.writelines(lines)
import os; os.rename(filename + ".new", filename)
Stefan
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 11:53

So nächstes Probelm :oops:

Mein jetziger Code:

Code: Alles auswählen

 sdatei = open('datei.txt)
 l = sdatei.readlines()
 sdatei.close()
 l.insert(5,'*INCLUDE,INPUT='+jobname+'.txt\n')
 sdatei = open('datei.txt','w')
 sdatei.write("".join(l))
 sdatei.close()
Der ganze Code steht in einer Schleife. jobname ist hierbei eine Variable. Das Problem ist nun, dass Python mir jedesmal in die Textdatei die Zeile *INCLUDE... einfügt. Aber eigentlich soll der sie nur einmal einfügen und es soll sich in jedem Durchlauf lediglich der jobname im Text ändern.
Hat da jemand ne Idee??
Alternativ könnte ich auch von Anfang an die Zeile
*INCLUDE,INPUT=
in meine Datei schreiben und Python füllt dann innerhalb der Schleife mit der richtigen Datei auf.
Ich hoffe man kann verstehen, was ich meine.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 17. März 2010, 12:35

Du hast da noch einige Punkte an denen Du verbessern kannst:

1. Würde ich der Ausgabedatei nicht den selben Namen wie der Eingabedatei geben.
2. Die Schleife kann man so natürlich nicht nachvollziehen, aber kann es sein, daß Du die Ausgabedatei in jedem Durchlauf öffnest und schließt?

Also von der Strategie her würde ich so vorgehen (das with-statement lasse ich mal weg, aber es würde Dir gut tun, mal das Tutorial ganz durchzulesen):

Code: Alles auswählen

fname = "datei.txt"
infile = open(fname)
outfile = open(fname[:-4] + ".changed", 'w')

# zeilenweise Iteration schont den Speicher
for line in infile:
    if condition:
        # modifizierte Zeile schreiben
    else:
        outfile.write(line) # kopie der eingelesenen Zeile

infile.close()
outfile.close()
Dieser Code ist nicht das Nonplusultra, aber ein Anfang zum Erklären:

- "condition" wäre etwas wie "my_query_string in line" - Du willst ja nur eine Zeile mit einem Inhalt Deiner Wahl ändern.
- Man kann in Python über Dateien zeilenweise iterieren (in anderen Sprachen natürlich auch) und so das .readlines() sparen. Das mag zwar hier und da nützlich und manchmal auch nicht schädlich sein, aber unterm Strich erlaubt einem die Iteration bessere Kontrolle.

Kann es sein, daß Du eine Art "Code-Generator" schreibst? Wenn ja, wozu? (Ich frage, weil sich damit möglicherweise eine bessere Möglichkeit für Dich eröffnet als die Dateien zu ändern.)

Gruß,
Christian

PS Das mit dem Durcharbeiten des Tutorials möchte ich wirklich empfehlen.
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 13:39

Zunächst vielen Dank Christian. Leider bekomme ich die if condition nicht hin. Eine Schande.
Kannst du mir ebtl sagen, was da hin muss?
Ich möchte jedesmal die Zeile:
*INCLUDE,INPUT=datei.txt
durch
*INCLUDE,INPUT=neuedatei.txt
ersetzen. Ich wäre dir sehr dankbar.
Die Tutorials schau ich mir mal an, wenn ich weniger Zeitdruck hab.

Mein Versuch:

Code: Alles auswählen

 fname = "datei.txt"
 infile = open(fname)
 outfile = open(fname[:-4] + ".changed", 'w')

 # zeilenweise Iteration schont den Speicher
 for line in infile:
    if (line == '*INCLUDE,INPUT='):
        infile.write('*INCLUDE,INPUT='+jobname+'.txt\n')# modifizierte Zeile schreiben
    else:
        outfile.write(line) # kopie der eingelesenen Zeile

 infile.close()
 outfile.close() 
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 17. März 2010, 14:07

nullstein hat geschrieben:Die Tutorials schau ich mir mal an, wenn ich weniger Zeitdruck hab.
Verständlich, aber letztlich der falsche Weg - sonst hättest Du Dein Problem längst gelöst ;-)

Also mit

Code: Alles auswählen

line == x
überprüfst Du, ob "line" und "x" identisch sind.
Mit

Code: Alles auswählen

x in line
überprüfst Du, ob "x" in "line" vorkommt.

Dein Skript wird aber auch nach der Korrektur auf die Schnauze fliegen, weil Du in "infile" zu schreiben versuchst, was aber nur zum Lesen geöffnet ist. Und außerdem willst Du wirklich darein schreiben? ;-)

Klammern nach if-statements sind in Python nicht nötig (aber manchmal nützlich, um die Übersichtlichkeit zu erhöhen).
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 17. März 2010, 14:11

Ach, und nochmal: Was willst Du eigentlich erreichen? Einen Verdacht habe ich ja schon formuliert. Also, wenn Du ein Programm mit versch. Paramteren anwerfen oder kompilieren willst, kannst Du das ggf. auch anders machen.
nullstein
User
Beiträge: 6
Registriert: Mittwoch 17. März 2010, 10:16

Mittwoch 17. März 2010, 14:55

So jetzt funktioniert alles. Vermutlich ist es alles andere als schön, aber mein Chef wollte ja quick and dirty :?
Ich danke dir nochmals Christian.
Mein Ziel ist es eine Optimierungsrechnung in ABAQUS zu automatisieren. Sprich via Python werden INPUT decks eingelesen, berechnet und bestimmte Ergebnisgrößen ausgelesen. Diese Ergebnisgrößen werden in eine txt geschrieben und dann wieder in das INPUT File eingebunden. Dies geschieht solange bis ein bestimmtes Kriterium erfüllt ist.
Wie gesagt: quick and dirty!! Hatte bis gestern noch nie mit Python zu tun. Dafür finde ich das Script doch recht ok. So jetzt erstmal Python Grundlagen lesen. :D

1000 Dank
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 17. März 2010, 16:38

Dann schau auch noch in das subprocess-Modul. ABAQUS kenne ich nicht, aber, wenn es Commandline-Input akzeptiert, ist das vielleicht was für Dich.

Viel Erfolg,
Christian
Antworten