2016-05-04 5 views
-2

ich einen Suchalgorithmus, die durch eine Log-Datei analysiert und fällt die Ergebnisse in dieses Format:Extrahieren von Daten aus einer Protokolldatei mit mehreren Leitungen Datensätze in CSV

[Mon May 2 13:46:00 2016]Local/ESSBASE///139969058175296/Info(4052237) 
Logging out user [[email protected] Directory], active for 0 minutes 
-- 
[Mon May 2 13:46:00 2016]Local/ESSBASE///139969068702016/Info(4052237) 
Logging out user [[email protected] Directory], active for 4 minutes 
-- 
[Mon May 2 13:46:01 2016]Local/ESSBASE///139969078176064/Info(4052237) 
Logging out user [[email protected] Directory], active for 6 minutes 
-- 
[Mon May 2 13:46:01 2016]Local/ESSBASE///69062385984/Info(4052237) 
Logging out user [[email protected] Directory], active for 45 minutes 
-- 
[Mon May 2 13:46:01 2016]Local/ESSBASE///69160071488/Info(4052237) 
Logging out user [[email protected] Directory], active for 3 minutes 
-- 
[Mon May 2 13:46:02 2016]Local/ESSBASE///969053964608/Info(4052237) 
Logging out user [[email protected] Directory], active for 3 minutes 

Ich brauche das Datum zu erhalten (IE : 5-2-2016 13:46:02), der Benutzer, der ausgeloggt wurde (IE: accelatisro @ Native Directory), und wie viele Minuten waren sie aktiv (IE: 45). Dann muss ich die Ergebnisse in ein komma-getrenntes Format schreiben, damit ich die Informationen in eine Datenbank hochladen kann (IE: 5-2-2016 13: 46: 02, accelatisro @ Natives Verzeichnis, 45). Die Datei ist ungefähr 45.000 Zeilen lang, so dass es von Hand gemacht wird, ist ein Nein.

Welchen Ansatz sollte ich für dieses Problem wählen?

+0

„Bitte dieses Programm schreiben, für mich“ Fragen sind hier nicht willkommen. Insbesondere sind sie zu breit - nicht auf eine bestimmte technische Frage beschränkt. –

+0

Hmm. Wahrscheinlich ist hier * eine zulässige Frage irgendwo versteckt. Ich werde sehen, ob ich ein wenig bearbeiten kann, um es herauszuziehen. –

+0

ja okay, also was ist, wenn Ihre Version der Frage besser ist: P – asdf

Antwort

0

Der einfache Ansatz besteht darin, einen regulären Ausdruck für jede Zeile zu schreiben, die Sie abgleichen müssen. Anschließend durchlaufen Sie die Datei, geben Daten aus jeder übereinstimmenden Zeile ein und geben diese Daten aus, wenn Sie den Datensatzbegrenzer sehen. Zum Beispiel:

#!/bin/bash 

l1_re='^\[([^\]+)]' 
l2_re='Logging out user \[([^\]+)], active for ([[:digit:]]+) minutes' 
delim='--' 

flush() { 
    [[ $time && $user && $minutes ]] || return 
    printf '%s,%s,%s\n' "${time//,/}" "${user//,/}" "${minutes//,/}" 
    time=; user=; minutes= 
} 

while IFS= read -r line; do 
    if [[ $line =~ $l1_re ]]; then 
    time=${BASH_REMATCH[1]} 
    elif [[ $line =~ $l2_re ]]; then 
    user=${BASH_REMATCH[1]} 
    minutes=${BASH_REMATCH[2]} 
    elif [[ $line = $delim ]]; then 
    flush 
    fi 
done 
flush 

Mit Ihrem gegebenen Eingang dieses aussendet:

Mon May 2 13:46:00 2016,[email protected] Directory,0 
Mon May 2 13:46:00 2016,[email protected] Directory,4 
Mon May 2 13:46:01 2016,[email protected] Directory,6 
Mon May 2 13:46:01 2016,[email protected] Directory,45 
Mon May 2 13:46:01 2016,[email protected] Directory,3 
Mon May 2 13:46:02 2016,[email protected] Directory,3 
+0

Ein paar Fragen: Wie nimmt dieses Programm Input? Was bedeutet '-r' in der' while IFS = read -r Zeile; tun? – asdf

+0

@Michael, das 'read' liest eine Zeile von stdin, also lautet die Idee, dass Sie' ./convert out.csv' ausführen. In BashFAQ # 1 unter http://mywiki.wooledge.org/BashFAQ/001 finden Sie Hintergrundinformationen. –

+0

@Michael, ... das '-r' macht Bashslashes wörtlich zu interpretieren - ohne sie werden sie teilweise als Escape-Zeichen verarbeitet, so' 'foo' würde' \ foo' werden (als Beispiel). –

Verwandte Themen