Seite 1 von 1
Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Donnerstag 15. Juli 2010, 23:23
von ratna_fong
Hallo zusammen,
erlaubt mir bitte zum Punkt zu kommen:
datei001.txt :
zeile 1
zeile 2
zeile 3
datei002.txt:
zeile 4
zeile 5
zeile 6
datei003.txt:
zeile 7
zeile 8
zeile 9
Ich habe folgenden Code:
Code: Alles auswählen
import sys
final = open("ergebnis.txt", "wb")
for i in range(1,4) :
temp = open("hrl00" + str(i) + ".txt", "r")
for line in temp:
final.write(line)
temp.close()
final.close()
Code funktioniert, d.h. Ergebnis sieht wie erwünscht aus. Code zwar eventuell nicht so elegant, aber mir macht das nichts.
ergebnis.txt:
zeile 1
zeile 2
zeile 3
zeile 4
zeile 5
zeile 6
zeile 7
zeile 8
zeile 9
Nun, ich möchte etwas komplizierter machen. Wenn der Inhalt der Dateien sagen wir mal so aussieht:
datei001.txt:
Überschrift
Zeile 1
Zeile 2
datei002.txt:
Überschrift
Zeile 3
Zeile 4
datei003.txt:
Überschrift
Zeile 5
Zeile 6
Am Ende soll also so rauskommen:
Ergebnis.txt:
Überschrift
Zeile 1
Zeile 2
Zeile 3
Zeile 4
Zeile 5
Zeile 6
Bis auf die Erste soll also aus jeder Datei jeweils ab der 2. Zeile in ergebnis.txt geschrieben werden.
Habt Ihr vielleicht mal eine Idee? Ich danke Euch für Eure Hilfe.
Viele Grüße,
Eure Ratna

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Donnerstag 15. Juli 2010, 23:53
von EyDu
Du möchtest enumerate oder itertools.islice verwenden.
Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 01:05
von ratna_fong
vielen Dank für den Tipp, hab ich direkt probiert.

Erstmal ganz einfach, allerdings schon direkt mit Fehlern behaftet
Code: Alles auswählen
import itertools
final = open("datei.txt", "r")
endfinal = itertools.islice(final, 1, None)
print endfinal
final.close()
Ich hab also versucht, die 1. Zeile auszulassen und den Rest zu printen.
vielleicht liegts an final als Parameter in der Methode? final ist doch iterierbar, müsste doch eigentlich klappen.
Mhhh..
Danke für die Hilfe.
Eure Ratna

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 02:32
von pillmuncher
ratna_fong hat geschrieben:Code funktioniert, d.h. Ergebnis sieht wie erwünscht aus. Code zwar eventuell nicht so elegant, aber mir macht das nichts.
Mir schon. Und dir auch, selbst, wenn du es jetzt noch nicht glaubst. Es ist aber nichtmal eine Frage der Eleganz, sondern eine bzgl. der Fehleranfälligkeit. Wenn du
with ...: verwendest, ist garantiert, dass die Datei wieder geschlossen wird. So wie du das machst, bleibt die Datei geöffnet, wenn zwischen
file = open() und
file.close() eine Exception fliegt, denn dann wird letzteres nicht ausgeführt.
Und Strings mit
+ zusammenzubasteln, ist meistens auch nicht klug.
Versuch lieber das hier:
Code: Alles auswählen
with open("ergebnis.txt", "wb") as out_file:
for num in xrange(1,4):
with open("hrl00%d.txt" % num, "r") as in_file:
# <-- hier die erste Zeile aus dem gerade geöffneten in_file lesen
# <-- hier die gelesene Zeile des ersten in_files in das out_file schreiben
out_file.writelines(in_file)
Dann willst du natürlich
das hier lesen.
Oder du machst es wie EyDu beschrieben hat, das geht genauso. Du schreibst zwar was von "mit Fehlern behaftet", aber bei mir funktioniert dein Code fehlerfrei. Was du als Fehler bezeichnest, ist vermutlich eine Ausgabe der Art
<itertools.islice object at 0x00D4AF90>. Das ist vielleicht nicht das, was du erwartest, aber es ist das, was du programmiert hast. Versuch mal:
Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 12:53
von ratna_fong
vielen Dank pillmuncher und Anderen,
richtig, "mit Fehlern behaftet" war falsch ausgedrückt, eine unerwartete Ausgabe wäre schon eher gewesen.
Ich habe den Vorschlagcode noch drangehangen und es hat einwandfrei funktioniert. Also:
Ich frage mich noch warum mein simpler Code eigentlich nicht das ausgibt, was ich wollte. Ich habe ein bisschen gegoogelt und in die Dokumentation reingeschaut. Es steht, dass die Methode itertools.islice "Make an iterator that returns selected elements from the iterable", also, sie spuckt bestimmte Elemente eines Interators. Meine datei.txt sieht doch so aus:
Überschrift
Zeile 1
Zeile 2
Und open spuckt doch ein Fileobjekt aus, einen Iterator zeilenweise. Habt Ihr vielleicht einen Denkfehler hierbei entdeckt? Wäre mir echt dankbar.
Code: Alles auswählen
import itertools
final = open("datei.txt", "r")
endfinal = itertools.islice(final, 1, None)
print endfinal
final.close()
Schöne Grüße,
Eure Ratna
Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 13:08
von Hyperion
Du willst doch mehrere Dateien joinen.
Also musst Du das ganze schon mal in eine Funktion packen, die Du für mehrere Dateien nutzen kannst. Die Funktion braucht also den Dateinamen und eine Info, ob es sich um die erste Datei handelt, bei der ja die Überschrift mitgenommen werden soll.
Diese Info kann man letztlich als Startparameter der islice()-Funktion ansehen, also einfach ein Integer.
Bei der ersten Datei übergibst Du also eine 0, danach jeweils eine 1.
Code: Alles auswählen
def append_data(filename, startline):
with open(filename, "r") as infile:
return "\n".join(islice(infile, startline, None))
Nun musst Du nur noch eine Dateiliste erstellen und dazu den Startwert speichern. (Man könnte es mit Tupeln oder einem Dictionary lösen) Dann kannst Du die Rückgabewerte entsprechend joinen und am Schluss in eine Datei schreiben

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 13:31
von BlackJack
@Hyperion: Die Funktion ist unschön. Der Name scheint nicht zu passen, ausserdem sehe ich den Sinn von dem `join()` nicht. Zumal das Zeilenende da zuviel ist, denn die eingelesenen Zeilen haben das Zeichen ja selbst noch.
Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 14:32
von Hyperion
BlackJack hat geschrieben:@Hyperion: Die Funktion ist unschön. Der Name scheint nicht zu passen,
Stimmt! Als ich anfing hatte ich eine etwas andere Idee.
ausserdem sehe ich den Sinn von dem `join()` nicht. Zumal das Zeilenende da zuviel ist, denn die eingelesenen Zeilen haben das Zeichen ja selbst noch.
Ich dachte, dass man am Schluss alles als String zusammen setzen möchte. Aber ok man kann natürlich auch den Iterator zurückgeben und das ganze dann in der main() zusammensetzen. Ja, an die Zeilenendzeichen habe ich irgendwie nicht gedacht.
Aber hey, heute ist Freitag und im Büro hier gefühlte 35°

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 16:03
von BlackJack
@Hyperion: Man kann es auch überhaupt nicht zusammensetzen, es soll ja wieder in eine Datei geschrieben werden und Dateiobjekte haben was symmetrisches zu `readlines()`.

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 17:33
von Hyperion
BlackJack hat geschrieben:@Hyperion: Man kann es auch überhaupt nicht zusammensetzen, es soll ja wieder in eine Datei geschrieben werden und Dateiobjekte haben was symmetrisches zu `readlines()`.

Hyperion hat geschrieben:
Aber hey, heute ist Freitag und im Büro hier gefühlte 35°
Stimmt. So wollte er es haben

Re: Nochmal kurz, Inhalt mehrerer Dateien in eine Datei tun
Verfasst: Freitag 16. Juli 2010, 19:48
von pillmuncher
ratna_fong hat geschrieben:Ich habe ein bisschen gegoogelt und in die Dokumentation reingeschaut. Es steht, dass die Methode itertools.islice "Make an iterator that returns selected elements from the iterable", also, sie spuckt bestimmte Elemente eines Interators.
Nein, das hast du missverstanden.
itertools.islice(...) erzeugt ein Objekt. Dieses ist ein Iterator. In Python bedeutet das nichts anderes, als dass es ein bestimmtes Protokoll implementiert, dh. bestimmte Attribute bzw. Methoden, die ein bestimmtes Verhalten an den Tag legen. Die Methode next() zB. wirft die Exception StopIteration, wenn sie kein nächstes Element mehr liefern kann. Das
for-Statement "kennt" dieses Protokoll und benutzt es entsprechend. Die
for-Schleife:
macht letztlich nichts anderes als dieser Code:
Code: Alles auswählen
_iter = seq.iter()
while True:
try:
each = _iter.next()
except StopIteration:
break
# ...
Das Iterator-Protokoll wird
hier beschrieben. Files implementieren dieses Protokoll, deswegen kann man mit
for zeilenweise über sie iterieren. Genauso kann man über
itertools.islice-Objekte iterieren, weil sie dasselbe Protokoll implementieren. Ohne zu iterieren kommst du aber nicht an die Elemente eines Iterators. Mit
print endfinal wird eine String-Repräsentation des Iterator-Objekts
endfinal selbst ausgegeben, aber nicht eine seiner Elemente. Was du hier fälschlicherweise erwartet hast, ist vergleichbar damit, dass du eine Druckmaschine anschaust, um zu wissen, was in der Zeitung steht, die sie druckt.
HTH,
Mick.