Seite 1 von 1
.txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 09:57
von smoothcode
Servus allerseits,
folgendes Problem, ich habe ein Verzeichnis mit 10 .txt/Text Dateien, davon
enthalten 5 .txt Datein im Header einen String namens "WNR" in der ersten Zeile.
Ich möchte nur die .txt Datein via Print ausgeben die diesen String enthalten.
Danach die Zeilenanzahl mit Count jeder einzelnen Datei bestimmen.
Wie wäre das einfach möglich?
Ich habe hier schonmal was gebaut..
Code: Alles auswählen
import glob
path = 'work/*.txt'
files=glob.glob(path)
for file in files:
f=open(file, 'r')
print '%s' % f.readlines()
f.close()
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 10:37
von BlackJack
@smoothcode: Brich das Problem in kleinere Unterprobleme herunter und schreibe dann jeweils eine Funktion die ein Teilproblem löst. Wenn Du die Funktionen getestet hast, kannst Du sie zu einer grösseren (Teil)Lösung zusammen setzen. Solange bis das gesamte Problem gelöst ist.
Anmerkungen zum Quelltext: `files` und `file` passen als Namen nicht zum jeweiligen Wert, weil es sich nicht um Dateien handelt sondern nur um Datei*namen*. Ein Datei-Objekt ist das was man von `open()` als Rückgabewert bekommt.
Dateien sollte man wenn möglich zusammen mit der ``with``-Anweisung öffnen, damit sie unter allen Umständen auch am Ende des ``with``-Blocks wieder geschlossen werden.
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 10:45
von /me
smoothcode hat geschrieben:
Es sieht schwer so aus, als sei diese Zeile der Ansatzpunkt. Ersetze sie durch eine Funktion, die über alle Zeilen der Datei läuft (und dabei in der ersten Zeile auf das Vorhandensein von 'WNR' prüft) und diese gegebenenfalls zählt und ausgibt.
Für den grundsätzlichen Ansatz würde mir folgendes einfallen.
Code: Alles auswählen
def do_work(textfile):
for linenumber, text in enumerate(textfile):
[...]
Die Schleife kannst du verlassen, wenn du in der ersten Zeile den gesuchten String nicht findest. Falls doch, dann gibst du einfach die Zeilen aus und kannst am Ende über
linenumber auch noch die Zahl der Zeilen ermitteln.
Ich würde das wohl noch etwas feiner granulieren, aber für einen ersten Ansatz reicht das.
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 10:49
von smoothcode
Code: Alles auswählen
import glob
import os
os.chdir( "work" )
for file in glob.glob('*.TXT'):
with open(file) as f:
contents = f.read()
if 'WNR' in contents:
f.close()
print file
Damit bekomme ich auf jedenfall alle Datein mit dem String WNR.
So müsste ich jetzt unter dem Code die Datei wieder Counten, die elegantere Lösung wäre
so wie ich denke, nen readline sowie den String finden in einem Rutsch.
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 10:52
von mutetella
@smoothcode
1. Würde ich Dateien immer mit dem
``with`` statement öffnen. Damit stellst Du sicher, dass die Datei in jedem Fall auch wieder ordentlich geschlossen wird.
2. Wenn Du die Datei offen hast, nimmst Du die erste Zeile via
`readline()` und schaust mit dem ``in`` Operator (
wie hier dokumentiert) nach, ob sich der String 'WNR' darin befindet.
3. Nun ermittelst Du die Anzahl der Zeilen. Das würde ich mit
`enumerate()` lösen. Diesem Wert addierst Du noch mit 1, da Du Dich durch das Lesen der ersten Zeile bereits auf der Zweiten befindest.
3. Somit hast Du alle Informationen, um die weitere Ausgabe zu steuern.
mutetella
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 10:55
von smoothcode
Fragt sich wie ich das Codemässig umsetze mit ReadLine..
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 11:03
von BlackJack
@smoothcode: Lass die Finger von `os.chdir()`. Das verändert das Arbeitsverzeichnis für den gesamten Prozess. Mit solchen Spässen sollte man gar nicht erst anfangen, weil einen das irgendwann ganz furchtbar in den A** beisst wenn man Dateioperationen in einem Arbeitsverzeichnis ausführt mit dem man so nicht gerechnet hat.
Dein Test prüft nicht ob 'WNR' in der ersten Zeile steht, sondern ob es *irgendwo* in der gesamten Datei steht. Dazu wird die gesamte Datei in den Speicher gelesen. Auch die Dateien bei denen kein 'WNR' in der ersten Zeile steht, wo man also gar nicht über die erste Zeile hinaus lesen müsste.
Wenn man Dateien mit ``with`` zusammen öffnet, dann braucht man kein `close()` mehr, das erledigt die ``with``-Anweisung ja gerade für einen. An *der* Stelle im Programmfluss wäre ein Schliessen der Datei auch unpassend, denn wenn ``with`` das nicht schon machen würde, dann würdest Du so nur Dateien schliessen, die 'WNR' enthalten, und alle anderen nicht.
Statt `readline()` wie vorgeschlagen wurde, würde ich die `next()`-Funktion verwenden. Das ist universeller, weil das bei jedem iterierbaren Objekt funktioniert und nicht nur bei Dateiobjekten.
Der Name `f` ist zu kurz und nichtssagend. Hier würde sich zum Beispiel `lines` anbieten.
Zum ermitteln der Anzahl von Elementen in einem iterierbaren Objekt kann man auch die `sum()`-Funktion mit einem Generatorausdruck verwenden um 1 für jedes Objekt im „iterable” aufzusummieren.
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 5. Juni 2014, 11:07
von smoothcode
Ok ich versuche es.
Re: .txt Datein die bestimmten String enthalten ausgeben.
Verfasst: Donnerstag 12. Juni 2014, 07:21
von BlackJack
Code: Alles auswählen
#!/usr/bin/env python
from __future__ import print_function
from glob import iglob
def main():
for filename in iglob('work/*.txt'):
with open(filename, 'r') as lines:
if 'WNR' in next(lines):
#
# Add 1 because of the first line already consumed by the test.
#
line_count = sum(1 for _ in lines) + 1
print('{0!r} contains {1} lines'.format(filename, line_count))
if __name__ == '__main__':
main()