Seite 1 von 1

Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 12:11
von power74
Hallo Forum

Ich habe eine Logdatei (derzeit ca. 50MB) die ich gerne auswerten möchte.
Die Logzeilen sehen in etwa so aus:

Code: Alles auswählen

2017-01-29 22:11:21: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:12:37: ACTION[Server]: Lor.....(Text bis ans Ende der Zeile)
2017-01-29 22:14:31: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:14:24: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:16:11: ACTION[Server]: Lor.....(Text bis ans Ende der Zeile)
2017-01-29 22:18:27: ACTION[Server]: 7Zbb.....(Text bis ans Ende der Zeile)
Die Idee ist, dass erstens nach den Zeichen nach [Server]: sortiert wird (also ABC,Lor,7Zbb) und als zweites Kriterium nach dem Datum/der Zeit.
Das Problem ist, dass die Zeichen nach dem Wort [Server]: beliebig sein können. Dort stehen unvorhersehbare Fantasienamen.
Die sortierte Datei sollte in einer neuen Textdatei ausgegeben werden.

Ist das überhaupt lösbar?

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 13:01
von BlackJack
@power74: Ja das ist möglich. Die `sort()`-Methode auf Listen oder die `sorted()`-Funktion kennen dafür das `key`-Argument das eine Funktion oder Methode erwartet die ein Element als Argument bekommt und den Wert nach dem sortiert werden soll als Ergebnis liefern muss. Also in diesem Fall zum Beispiel ein Tupel aus der Zeichenkette und dem Datum.

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 13:29
von power74
OK aber wie schreibe ich im Code, dass das Wort nach ACTION[Server]: so ein Schlüsselwort für die Sortierung ist.

Könntest du bitte anhand der Logbeispiele zeigen, wie so ein Code aussehen müsste, der nach beliebigen (noch nicht bekannten) Begriffen sortieren kann (nebst dem Datum)? Vom Konzept her müsste man doch erst mal alle diese Begriffe einlesen und dann die Zeilen mit demselben Begriff gruppieren und dann innerhalb dieser Gruppe noch nach Datum/Zeit sortieren. Oder denke ich da noch um sieben Ecken rum?

Ungefähr so schwebt mir das im Kopf rum aber ich als "Hochseedampfunterseebootkapitänsgehilfe" :) habe damit erhebliche Mühe sowas aufs Papier/den Bildschirm zu kriegen, sorry... ich hab' noch zu wenig Übung mit programmieren.
Der zu beachtende Begriff beginnt nach dem Leerzeichen nach [Server]: und endet vor dem nächsten Leerzeichen - so würde ich das umgangssprachlich definieren.

Natürlich kannst du argumentieren, dass ich die von dir genannten Ansätze erst mal studieren soll (hast recht ja, sollte ich) - aber dann muss ichs wohl auf die nächsten Ferien verschieben... daher meine Bitte.

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 13:38
von BlackJack
@power74: Du brauchst nur eine Funktion die *eine* Zeile in ein Tupel überführt mit den Werten nach denen sortiert werden soll in der Reihenfolge in der sortiert werden soll. Die Funktion übergibst Du `sort()` oder `sorted()`, die machen dann den ganzen Rest. Wie kompliziert die Funktion wird, hängt davon ab wie die Logdatei tatsächlich aussieht. Also was fest und was variabel ist.

Code: Alles auswählen

In [10]: line
Out[10]: '2017-01-29 22:11:21: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)'

In [11]: line.partition(': ACTION[Server]: ')
Out[11]: 
('2017-01-29 22:11:21',
 ': ACTION[Server]: ',
 'ABC.....(Text bis ans Ende der Zeile)')

In [12]: timestamp, _, text = line.partition(': ACTION[Server]: ')

In [13]: (text, timestamp)
Out[13]: ('ABC.....(Text bis ans Ende der Zeile)', '2017-01-29 22:11:21')
Und ich bin mir nach der Beschreibung nicht ganz sicher ob die gesamte Restzeile, oder nur ein Präfix davon und wenn ja nach welchen Kriterium dieser Präfix gewählt werden soll.

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 13:45
von nezzcarth
Wenn der beliebige Text keine Leerzeichen enthält, könnte das im einfachsten Fall vielleicht so aussehen:

Code: Alles auswählen

#!/usr/bin/env python3
from operator import itemgetter
 
def main():
    with open('log.txt', 'r') as fh:
        lines = [line.split() for line in fh]
    for line in sorted(lines, key=itemgetter(0,1,4)):
        print(' '.join(line))

if __name__ == '__main__':
    main()

Code: Alles auswählen

$ cat log.txt
2017-01-29 22:18:27: ACTION[Server]: 7Zbb Lorem_Ispum
2017-01-29 22:14:24: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:11:21: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:12:37: ACTION[Server]: Lor Lorem_Ispum
2017-01-29 22:14:31: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:16:11: ACTION[Server]: Lor Lorem_Ispum

$ ./test.py  
2017-01-29 22:11:21: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:12:37: ACTION[Server]: Lor Lorem_Ispum
2017-01-29 22:14:24: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:14:31: ACTION[Server]: ABC Lorem_Ispum
2017-01-29 22:16:11: ACTION[Server]: Lor Lorem_Ispum
2017-01-29 22:18:27: ACTION[Server]: 7Zbb Lorem_Ispum
Wenn die Datei komplizierter ist, könnte man auch reguläre Ausdrücke verwenden. Auch das Zusammenfügen der Zeilen sähe dann natürlich anders aus, und kann ggf. so umgegangen werden, dass man sich die Originalzeilen in einem Dictionary merkt.

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 14:15
von BlackJack
@nezzcarth: Einer von uns beiden hat die Sortierkriterien falsch verstanden. Ich hatte das so verstanden das erst nach dem Text(präfix) und dann nach dem Zeitstempel sortiert werden soll, denn erst nach Datum und dann nach Textpräfix würde kein `key` benötigen, da kann man auch ganz normal die Zeilen sortieren lassen.

Ich hatte es so verstanden dass das Ergebnis so aussehen sollte:
[codebox=text file=Unbenannt.txt]2017-01-29 22:18:27: ACTION[Server]: 7Zbb.....(Text bis ans Ende der Zeile)
2017-01-29 22:11:21: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:14:24: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:14:31: ACTION[Server]: ABC.....(Text bis ans Ende der Zeile)
2017-01-29 22:12:37: ACTION[Server]: Lor.....(Text bis ans Ende der Zeile)
2017-01-29 22:16:11: ACTION[Server]: Lor.....(Text bis ans Ende der Zeile)[/code]

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 14:43
von nezzcarth
BlackJack hat geschrieben:@nezzcarth: Einer von uns beiden hat die Sortierkriterien falsch verstanden.
Ich glaube, ich :oops: Dein Ergebnis könnte man, wenn ich es richtig sehe, doch erreichen, in dem man in meinem Beispiel itemgetter andere Parameter gibt (itemgetter(3, 0, 1)), oder?

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Samstag 1. April 2017, 14:59
von BlackJack
@nezzcarth: Jup, das sollte gehen.

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Sonntag 2. April 2017, 20:29
von power74
Vielen Dank,

variabel ist alles was nach ACTION[SERVER]: kommt. Sortiert werden sollte als erstes nach dem Wort (ohne Leerzeichen) nach [SERVER]: und erst dann nach Datum/Zeit. Es soll dann aber immer die ganze Zeile (inkl. dem Text mit allen Leerzeichen) in die neue Datei kopiert und sortiert werden.

:?: Seid ihr noch immer derselben Meinung?

Re: Logdatei (Textfile) filtern und sortieren

Verfasst: Sonntag 2. April 2017, 23:15
von BlackJack
@power74: Im Grunde ja. ``[Server]`` hatte bis jetzt noch niemand auf dem Schirm weil da nicht wirklich ersichtlich war ob das Variabel ist und falls ja ob es irgendwie ins Ergebnis einfliessen sollte. Das Prinzip bleibt aber das gleiche.