python
from pathlib import Path
quelle = Path('server.log')
ziel = Path('errors.txt')
try:
zaehler = {}
with quelle.open(encoding='utf-8') as eingabe, ziel.open('w', encoding='utf-8') as ausgabe:
for zeile in eingabe:
teile = zeile.split(maxsplit=3) # Datum, Uhrzeit, Stufe, Rest
if len(teile) < 3:
continue # kaputte Zeile überspringen
stufe = teile[2]
zaehler[stufe] = zaehler.get(stufe, 0) + 1
if stufe == 'ERROR':
ausgabe.write(zeile)
except FileNotFoundError:
print(f'Datei {quelle} nicht gefunden')
else:
for stufe, n in sorted(zaehler.items()):
print(f'{stufe}: {n}')
Was passiert:
quelle.open(...)ist diePath-Schreibweise vonopen(quelle, ...). Mit einem einzigenwithwerden zwei Dateien geöffnet und am Ende beide geschlossen.zeile.split(maxsplit=3)zerlegt höchstens an drei Stellen. So landet der Rest der Zeile (die Meldung, die selbst Leerzeichen enthält) unzerteilt im vierten Element. Das Element mit Index 2 ist die Stufe.- Die Prüfung
len(teile) < 3verhindert einenIndexErrorbei leeren oder kaputten Zeilen.continuespringt zur nächsten Zeile. - Wenn
server.logfehlt, löstopeneinenFileNotFoundErroraus. Derexcept-Block fängt genau diesen Fehler ab und gibt eine verständliche Meldung aus. - Der
else-Block läuft nur, wenn alles geklappt hat. Dort steht die Ausgabe der Zählung, denn sie soll nicht erscheinen, wenn die Datei fehlt.
Warum so: Gefangen wird gezielt der eine erwartbare Fehler, alle anderen (zum Beispiel ein Programmierfehler) sollen sichtbar bleiben. Zeilenweises Lesen ist speicherschonend und funktioniert auch bei Gigabyte-Dateien.