Seite 1 von 1
Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Dienstag 26. April 2016, 14:41
von python95
Hallo zusammen,
ich bin relativ unerfahren mit python.
Ich möchte ein Skript erstellen, welches eine Datei einliest und anschließend unterschiedliche Zeilen der Datei in unterschiedliche neue Dateien speichert.
Mir geht es nicht um das öffnen einer Datei, sondern eher um das herausschreiben und in neuen Dateien abspeichern.
Folgender ablauf:
Code: Alles auswählen
if line.startswith(ABC):
Kopiere Zeile die mit ABC beginnt + die 2 darauffolgenden Zeilen in DATEI A
if line.startswith(DEF):
Kopiere Zeile die mit DEF beginnt + die 5 darauffolgenden Zeilen in DATEI B
if not line.startswith(ABC) and line.startswith(DEF): #ist das so überhaupt möglich, oder gibt es vllt eine andre Idee die restlichen Zeilen zu speichern
Kopiere alles in DATEI C
Kann mir hierbei jemand weiterhelfen?
Ich glaube es müssen 3 Listen für die DATEI A-C erstellt werden.
Bin über jede Hilfe dankbar!
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Dienstag 26. April 2016, 15:02
von BlackJack
@python95: Was die Verzweigungen angeht, schau Dir mal ``if``, ``elif``, und ``else`` an.
Du könntest die Daten in drei Listen im Speicher sammeln, aber auch direkt in drei verschiedene Dateien schreiben.
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Dienstag 26. April 2016, 15:17
von BlackJack
Ungetestet:
Code: Alles auswählen
from __future__ import absolute_import, division, print_function
from itertools import islice
def iter_lines(filename):
with open(filename) as lines:
for line in lines:
yield line
def main():
with open('a.txt', 'w'), open('b.txt', 'w'), open('c.txt', 'w') as (
file_a, file_b, file_c
):
lines = iter_lines('test.txt')
for line in lines:
if line.startswith('ABC'):
file_a.write(line)
file_a.writelines(islice(lines, 2))
elif line.startswith('DEF'):
file_b.write(line)
file_b.writelines(islice(lines, 5))
else:
file_c.write(line)
if __name__ == '__main__':
main()
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Dienstag 26. April 2016, 16:12
von python95
danke dir für die schnelle Hilfe!
Ich werde es morgen gleich mal ausprobieren und mich melden.
Vielen dank

Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 07:05
von python95
Also ich komm der Sache schon etwas näher, aber ich hab mich vielleicht etwas schlecht ausgedrückt.
Aber zu Beginn definiere ich 2 Leere Listen und möchte in diese die Zeilen reinschreiben.
Sprich:
Code: Alles auswählen
newDateiA = open(... +'DATEI_A.txt' , "w")
newDateiB = open(... +'DATEI_B.txt' , "w")
outDateiA = []
outDateiB = []
for line in lines:
if i < len(lines):
if line.startswith("ABC"):
Schreibe die Zeile und die 2 darauffolgenden in Liste DateiA
Ist wenn man den Durchblick hat bestimmt nicht schwer

Danke!
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 07:38
von python95
Und das mit dem if, elif und else ist gut, aber ich möchte die darauffolgenden Zeilen (welche nicht mit ABC bzw. DEF beginnen) nicht im letzten file haben.

Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 08:18
von BlackJack
@python95: Dann musst Du das halt von schreiben in Dateien auf anhängen und erweitern von Listen umschreiben. Das mit den 2 beziehungsweise 5 Folgezeilen habe ich schon verstanden und auch im Programm berücksichtigt. Du müsstest jetzt halt mal nachvollziehen was das Programm macht.
Edit: Wobei ich jetzt etwas verwirrt bin, dass Du Dateien öffnest *und* Listen anlegst. Was denn nun? (Und die Namensschreibweise entspricht nicht dem
Style Guide for Python Code.)
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 12:45
von BlackJack
Eine (ungetestete) Lösung mit Listen und ohne ``if``/``elif``/``else``-Konstrukt.
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from itertools import islice
class LineCollector(object):
def __init__(self, prefix='', extra_line_count=0):
self.prefix = prefix
self.extra_line_count = extra_line_count
self.lines = list()
def __call__(self, line, lines):
line_matches = line.startswith(self.prefix)
if line_matches:
self.lines.append(line)
self.lines.extend(islice(lines, self.extra_line_count))
return line_matches
def main():
line_collectors = [
LineCollector('ABC', 2), LineCollector('DEF', 5), LineCollector()
]
with open('test.txt') as lines:
for line in lines:
has_matched = any(c(line, lines) for c in line_collectors)
assert has_matched, 'The last collector should match every string'
lines_a, lines_b, lines_c = (c.lines for c in line_collectors)
# ...
if __name__ == '__main__':
main()
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 13:19
von python95
Code: Alles auswählen
outDATEIA = []
for line in lines:
if i < len(lines):
if line.startswith("ABC /"):
print(line)
outDATEIA.append(line)
#outDATEIA.append(lines.next()) #funktioniert nicht
Hier ein Ausschnitt, es wird mir die Zeile die ABC beginnt in die Liste outDATEIA geschrieben.
Ich habe nur Probleme, damit ich die folgende reingeschrieben wird
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 14:13
von BlackJack
@python95: Die Namensschreibweisen werden ja immer schlimmer…
Ich stehe immer noch zu meiner Lösung. Das Du da so ein `i` anscheinend irgendwie selber hochzählst ist sehr wahrscheinlich ganz gruselig. Wozu ist das gut? Was bedeutet das `i`?
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 14:47
von python95
Danke für deine schnellen Hilfe, habe es jetzt hinbekommen!
Die Namensschreibweisen sind vllt nicht die besten, aber es soll ja einfach nur funktionieren

:D
i ist die Zeile der datei, welche eingelesen wird.
Also es funktioniert jetzt bis auf, dass in Liste outDATEIB auch die folgezeilen enthalten sind. -
ist wahrscheinlich auch nichts großes mehr.
Code: Alles auswählen
i=0
outDATEIA = []
outDATEIB = []
for line in lines:
if i < len(lines):
#print(i)
if line.startswith("ABC"):
#print(i)
#print(lines[i+1])
outDATEIA.append(line)
outDATEIA.append(lines[i+1])
outDATEIA.append(lines[i+2])
elif line.startswith("DEF"):
#print(line)
outDATEIA.append(line)
outDATEIA.append(lines[i+1])
outDATEIA.append(lines[i+2])
outDATEIA.append(lines[i+3])
outDATEIA.append(lines[i+4])
outDATEIA.append(lines[i+5])
outDATEIA.append(lines[i+6])
else:
#print(line)
outDATEIB.append(line)
i=i+1
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 15:06
von /me
python95 hat geschrieben:Die Namensschreibweisen sind vllt nicht die besten, aber es soll ja einfach nur funktionieren

:D
Nichtssagende oder falsch gewählte Namen sind ein erstes Warnzeichen dafür, dass der Code nicht in Ordnung ist. Selbst wenn er in Ordnung sein sollte macht die Verwendung schlechter Bezeichnernamen eine Wartung unnötig schwer.
python95 hat geschrieben:Also es funktioniert jetzt bis auf, dass in Liste outDATEIB auch die folgezeilen enthalten sind. -
ist wahrscheinlich auch nichts großes mehr.
Du hast eine merkwürdige Lösung aufgebaut mit überflüssigen Anweisungen (
if i < len(lines):). So lange du nicht verstehst was du programmierst ist das Problem doch groß, zumindest zu groß für dich. BlackJacks Lösung funktioniert übrigens problemlos - es sei denn, du zauberst auf einmal noch mehr uns bislang unbekannte Randbedingungen aus dem Hut.
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 16:42
von BlackJack
@python95: Aus *drei Ausgabedateien* sind jetzt *zwei Listen* geworden und aus 5 zusätzlichen Zeilen im 'DEF'-Fall sind 6 geworden. Das müsste man bei meinen Lösungen natürlich entsprechend berücksichtigen.
Die aktuelle Zeile ist ja schon an den Namen `line` gebunden. Einen Index braucht man da nicht. Zudem ist `i` nicht die Zeile der Datei die eingelesen wird, denn eine (Eingabe)Datei gibt es an der Stelle ja bereits nicht mehr, denn `lines` scheint eine Sequenz zu sein (Liste wahrscheinlich). Das mit dem Index funktioniert so nicht, wie Du ja selbst bereits bemerkt hast. Denn der hat ja keinen Einfluss auf den Iterator den die äussere Schleife verwendet. Wie man das mit `islice()` ohne Index löst, habe ich ja bereits gezeigt. Dafür muss `lines` ein Iterator sein. Ein einfachsten gleich die zum lesen geöffnete Datei.
Wir müssen die Namen lesen und wenn sie schlecht gewählt sind, dann ist es schwieriger zu verstehen was da passieren soll. Und auch für Dich wird das spätestens nach einiger Zeit zu einem Problem, wenn Du die Zuordnung von Namen zu Bedeutungen nicht mehr so frisch im Kopf hast.
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 18:48
von python95
Ja tut mir leid. Ich hab mich zu Beginn nicht gut ausgedrückt und seitdem hat sich eine Kleinigkeit mit der Ausgabedatei geändert.
Also beim Ausführen des Skriptes, kann man ein File einlesen.
Anschließend wird dieses nach der Zeile die mit ABC startet durchsucht und speichert diese Zeile + 2 Folgezeilen in DATEIA.
Darauf folgt die Durchsuchung nach DEF und speichert diese Zeile + 6 Folgezeilen ebenso in DATEIA.
Stand jetzt werden alle Zeilen (bis auf die, die mit ABC/DEF beginnen) in DATEIB gespeichert.
Somit ist das Problem, dass die "Folgezeilen" nicht in DATEIB gespeichert werden sollen.
Sorry für die schlechte Formulierung und Änderung!
Anbei der komplette Code, der bis auf das "Problem" macht was er soll.
Vielleicht erklärt das dann etwas mehr.
Code: Alles auswählen
import os
import re
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename
from tkinter.messagebox import showerror
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("waehle_datei")
Label(self, text='waehle_datei').grid(row=0, sticky=N+E)
self.master.rowconfigure(5, weight=1)
self.master.columnconfigure(5, weight=1)
self.grid(sticky=N+E+S+W)
global knopf1
self.knopf1 = Button(self, text="Browse", command=self.load_file, width=10)
self.knopf1.grid(row=1, column=0, sticky=N+E+S+W)
global knopf2
self.knopf2 = Button(self, text="Execute!", command=self.Uebersetzung, width=10)
self.knopf2.grid(row=2, column=0, sticky=N+E+S+W)
def load_file(self):
global fname
fname = askopenfilename(filetypes=(("PC_FILES", "*.pc;*.inc"),
("N_FILES", "*.nas;*.dat"),
("ALL_FILES", "*.*") ))
if fname:
try:
print("""file wird geladen: self.settings["template"].set(fname)""")
print(fname)
except:
showerror("Open Source File", "Failed to read file\n'%s'" % fname)
return
def Uebersetzung(self):
ori = open(fname, "r")
func = str(ori)
lines=ori.readlines()
# Erstellt 2 neue .inc Dateien
if func.find(".inc")>0:
newDATEIA = open(os.path.splitext(ori.name)[0] + '_neueA.inc' , "w")
newDATEIB = open(os.path.splitext(ori.name)[0] + '_neueB.inc' , "w")
i=0
outDATEIA = []
outDATEIB = []
for line in lines:
if i < len(lines):
if line.startswith("ABC"):
outDATEIA.append(line)
outDATEIA.append(lines[i+1])
outDATEIA.append(lines[i+2])
elif line.startswith("DEF"):
outDATEIA.append(line)
outDATEIA.append(lines[i+1])
outDATEIA.append(lines[i+2])
outDATEIA.append(lines[i+3])
outDATEIA.append(lines[i+4])
outDATEIA.append(lines[i+5])
outDATEIA.append(lines[i+6])
else:
outDATEIB.append(line)
i=i+1
for o in outDATEIA:
newDATEIA.write(o)
for p in outDATEIB:
newDATEIB.write(p)
### ENDE ###
if __name__ == "__main__":
MyFrame().mainloop()
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Mittwoch 27. April 2016, 19:56
von Sirius3
@python95: erst einmal ein paar Bemerkungen zu Deinem Code. Du solltest keine *-Importe verwenden, da Du nicht kontrollieren kannst, welche Namen da in den Namensraum geladen werden. Bei tkinter sind das ungefähr 700 Stück. Vergiss am besten gleich wieder, dass es das Schlüsselwort global gibt. Braucht man einen Zustand über das Ende einer Methode, dann gibt es ja bei der Objektorientierten Programmierung Attribute dafür. Zudem definierst Du knopf1 und knopf2 in __init__ gar nicht. Die Methode load_file lädt gar keine Datei, sondern fragt nur nach einem Dateinamen. Nackte excepts sollte man nicht verwenden, weil sie das Suchen von Fehlern quasi unmöglich machen. Welche Exception, glaubst Du, kann bei zwei print-Aufrufen auftreten? Um die Dateiendung zu ermitteln, gibt es os.path.splitext, der Weg über das Suchen eines Substrings in der Stringrepräsentation des Fileobjekts ist deutlich umständlicher und schwerer zu verstehen. newDATEIA und newDATEIB werden nur definiert, falls die Dateiendung .inc ist, d.h. in allen anderen Fällen bricht die Funktion mit einem NameError ab. Was soll denn passieren, wenn die Endung nicht .inc ist?
Dateien, die man öffnet, sollte man auch wieder schließen. Gerade wenn man in Dateien schreibt, könnte es passieren, dass nicht alle Daten geschrieben werden, wenn man die Datei nicht ordnungsgemäß schließt.
Eine weitere Lösung könnte so aussehen:
Code: Alles auswählen
def split_file(filename):
base_n_ext = os.path.splitext(filename)
lines = open(filename)
new_file_a = open('%s_neueA%s' % base_n_ext, 'w')
new_file_b = open('%s_neueB%s' % base_n_ext, 'w')
lines_for_a = 0
for line in lines:
if line.startswith("ABC"):
lines_for_a = 3
elif line.startswith("DEF"):
lines_for_a = 7
if lines_for_a > 0:
lines_for_a -= 1
new_file_a.write(line)
else:
new_file_b.write(line)
new_file_a.close()
new_file_b.close()
lines.close()
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Donnerstag 28. April 2016, 06:50
von python95
Danke Sirius3 für deine Bemühungen.
Ich glaube dir gern, dass dein Code funktioniert und um Welten besser ist, leider kann ich ihn nicht so in mein vorhandenen einbauen, das es funktioniert.
Die Endung ist ausschließlich .inc, daher sollte das kein problem darstellen.
Trotzdem vielen Dank für die Hilfe!
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Donnerstag 28. April 2016, 08:29
von python95
hab's hinbekommen!
erledigt.
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Donnerstag 28. April 2016, 19:32
von python95
@sirius3
ich habe es jetzt mit deinem codebeispiel hinbekommen, damit ist es echt um einiges schneller! vielen dank.
könnte man da noch iwie einbauen, dass wenn die Folgezeilen (die kopiert werden) mit einer # beginnen ignoriert werden?

Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Donnerstag 28. April 2016, 20:14
von Sirius3
@python95: natürlich kann man das. startswith kennst Du ja schon.
Re: Skript: Datei durchsuchen und bestimmte Sachen in neue Dateien speichern
Verfasst: Freitag 29. April 2016, 07:17
von python95

"continue" war das, was gefehlt hat. Jetzt läuft's wie es soll, merci!