Anfängerfrage: Datei einlesen, prüfen und ausgeben

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
merlin_emrys
User
Beiträge: 110
Registriert: Freitag 3. März 2006, 09:47

Ich lege mit meinem eigentlich in Arbeit befindlichen Programm gerade mal eine Pause ein und bastele an einem anderen kleinen Projekt. Dafür wollte ich ein Hilfsprogramm schreiben, das folgendes macht:
- eine Datei unbekannter Länge "test.txt" zum Lesen öffnen
- eine Datei "zieltest.txt" zum Schreiben öffnen
- "test.txt" zeilenweise einlesen, jede Zeile auf das Vorhandensein eines Strings prüfen, und wenn der String nicht enthalten ist, die Zeile so, wie sie war, in "zieltest.txt" schreiben.
- alle Dateien wieder zumachen

Was ich zusammengebastelt habe, sieht folgendermassen aus:

Code: Alles auswählen

import  string

original = open ("Test.txt", "a")
original.write("Textende erreicht ")
original.close
origin = open ("Test.txt", "r")
target = open ("Zieltest.txt", "a")
i = 0
pruefzeile = origin.readline(i)
while pruefzeile != "Textende erreicht ":
    zeilenstring = str(pruefzeile)
    if zeilenstring.find("de ") == -1:
        #target.write(zeilenstring)
        print zeilenstring
    i += 1
    pruefzeile = origin.readline(i)
target.close
origin.close
print "Fertig"
Derzeit habe ich damit noch mindestens drei Probleme:
1.) das Programm gibt unterschiedslos Zeilen aus, die ein oder die kein "de " enthalten. Er schreibt einfach alle Zeilen auf den Bildschirm (oder in eine Datei).
2.) Nach "Textende erreicht " schreibt diese Version munter weiter Leerzeilen auf den Bildschirm. Die Version mit aktiver Zeile 13 erzeugt Dateien beliebiger Grösse, je nachdem wie lange man wartet, bis man manuell abbricht.
3.) Ich kann die Dateien, die ich via Zeile 13 erzeugt habe, erst löschen, wenn ich Python beendet habe. Kein Wunder, der "close"-Befehl wird ja auch nicht ausgeführt, WinXP will aber keine geöffneten Dateien löschen. Wie kann ich die Dateien schliessen?

1. und 2. sprechen dafür, dass meine Art, Strings zu vergleichen, grundsätzlich nicht funktionieren. Aber auch alle anderen Versionen, die ich mal probiert habe, wollten nicht funktionieren... Insofern bitte ich mal wieder um Hilfe.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

1. Wenn du Funktionen ohne Parameter aufrufst, musst du immer die Klammern schreiben.
"foo.close" ist eine Referenz auf die Methode "close" von "foo". Du musst "foo.close()" schreiben.

2. Readline liest die nächste Zeile ein. Der Optionale Parameter gibt nicht an, welche Zeile, der hat eine andere Bedeutung (RTFM)

3. Statt find kannst du einfach den "in" Operator benutzen

4. Anstatt in der Originaldatei rumzuschreiben, lese doch einfach bis zum Dateiende ;) Das erkenst du daran, dass readline "" zurückgibt.

5. Statt Readline kannst du ebenfalls den "in" Operator benutzen.

Dein Programm kann man also einfach so schreiben:

Code: Alles auswählen

original = open("Test.txt", "r")
ziel = open("Ziel.txt","w")
for line in original:
  if "de " not in line:
    ziel.write(line)
original.close()
ziel.close()
Übrigens gibt es für sowas grep mit der Option "-v"
merlin_emrys
User
Beiträge: 110
Registriert: Freitag 3. März 2006, 09:47

@ Joghurt: Tausend Dank!
Joghurt hat geschrieben:1. Wenn du Funktionen ohne Parameter aufrufst, musst du immer die Klammern schreiben.
"foo.close" ist eine Referenz auf die Methode "close" von "foo". Du musst "foo.close()" schreiben.
Hmm... Das muss ich mir offenbar noch deutlich strikter angewöhnen. Ich versuch beim nächsten Mal gleich dran zu denken :-) .
Joghurt hat geschrieben:2. Readline liest die nächste Zeile ein. Der Optionale Parameter gibt nicht an, welche Zeile, der hat eine andere Bedeutung (RTFM)
TFM lesen != TFM verstehen :-( ... wie so oft. Nachdem es zu Anfang so aussah, als ob immer die erste Zeile gelesen würde, war meine Schlussfolgerung, ich müsste die Zeilen irgendwie "hochzählen". Und danach wurde es auch besser - frag mich nicht, warum, war vermutlich irgendeine Koinzidenz mit anderen Basteleien, die mich dann auf der falschen Spur gehalten hat.
Joghurt hat geschrieben:4. Anstatt in der Originaldatei rumzuschreiben, lese doch einfach bis zum Dateiende ;) Das erkenst du daran, dass readline "" zurückgibt.
Das setzt voraus, dass solche Zeilen nicht in der Datei selbst auftreten können. Um das zu beurteilen, müsste ich wissen, ob readline für eine Leerzeile einen Zeilenwechsel liest oder eben gar nichts... was in TFM nicht drinsteht (oder zumindest nicht da, wo ich gesucht habe), wie so vieles, was ich gern wüsste. Und in meinem Buch und den Tutorials habe ich es auch nicht gefunden. Also dachte ich, ich setze mir einfach ein bekanntes Textende, was ich dann abfragen kann.
Joghurt hat geschrieben:3. Statt find kannst du einfach den "in" Operator benutzen
5. Statt Readline kannst du ebenfalls den "in" Operator benutzen.
Das hat bei mir Fehlermeldungen erzeugt... aber jetzt ist mir auch aufgefallen, warum: Ich habe das "in" immer mit "for" kombiniert, nicht mit "if"... Anfängerfehler halt :oops:
Joghurt hat geschrieben:Übrigens gibt es für sowas grep mit der Option "-v"
Hmm... ich finde in der F1-Hilfe "grep" nur ohne weitere Erläuterungen unter "A.5 Obsolete " aufgelistet, und Learning Phyton verschweigt dessen Existenz offenbar ganz... Insofern will ich die Existenz und den Nutzen nicht in Abrede stellen, ich kann es nur nicht benutzen, weil ich nicht herausfinden kann, wie :o .

Trotzdem nochmal vielen Dank, ich hoffe, ich komme jetzt zurecht! :D
BlackJack

merlin_emrys hat geschrieben:
Joghurt hat geschrieben:4. Anstatt in der Originaldatei rumzuschreiben, lese doch einfach bis zum Dateiende ;) Das erkenst du daran, dass readline "" zurückgibt.
Das setzt voraus, dass solche Zeilen nicht in der Datei selbst auftreten können. Um das zu beurteilen, müsste ich wissen, ob readline für eine Leerzeile einen Zeilenwechsel liest oder eben gar nichts... was in TFM nicht drinsteht (oder zumindest nicht da, wo ich gesucht habe), wie so vieles, was ich gern wüsste.
Das steht z.B. im Tutorial unter 7.2.1 Methods of File Objects
Joghurt hat geschrieben:Übrigens gibt es für sowas grep mit der Option "-v"
Hmm... ich finde in der F1-Hilfe "grep" nur ohne weitere Erläuterungen unter "A.5 Obsolete " aufgelistet, und Learning Phyton verschweigt dessen Existenz offenbar ganz... Insofern will ich die Existenz und den Nutzen nicht in Abrede stellen, ich kann es nur nicht benutzen, weil ich nicht herausfinden kann, wie :o .
Joghurt meinte das Kommandozeilenprogramm ``grep``, nicht das Python-Modul. Das wie wäre in dem Fall wohl:

Code: Alles auswählen

marc@s8n:~$ grep -v 'de ' eingabe.txt > ausgabe.txt
lunar

BlackJack hat geschrieben: Joghurt meinte das Kommandozeilenprogramm ``grep``, nicht das Python-Modul. Das wie wäre in dem Fall wohl:

Code: Alles auswählen

marc@s8n:~$ grep -v 'de ' eingabe.txt > ausgabe.txt
Das könnte unter Windows XP unter anderem daran scheitern, daß grep für Windows XP nicht verfügbar ist.
BlackJack

lunar hat geschrieben:Das könnte unter Windows XP unter anderem daran scheitern, daß grep für Windows XP nicht verfügbar ist.
Nicht verfügbar? http://gnuwin32.sourceforge.net/
lunar

BlackJack hat geschrieben:
lunar hat geschrieben:Das könnte unter Windows XP unter anderem daran scheitern, daß grep für Windows XP nicht verfügbar ist.
Nicht verfügbar? http://gnuwin32.sourceforge.net/
Nachinstallieren kann man es natürlich. Bei mir ist sowieso cygwin installiert, weils ohne bash halt nicht geht. Aber standardmäßig wird es nicht mitgeliefert. Deswegen würde ich mich auch nicht auf das Vorhandensein von grep verlassen.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

merlin_emrys hat geschrieben:Das setzt voraus, dass solche Zeilen nicht in der Datei selbst auftreten können.
readline gibt "\n" bei einer reinen Leerzeile zurück.
Wenn readline "" zurückgibt, ist es immer das Dateiende.
Antworten