awk/sed Zeilen bei der Uhrzeit 3 Minuten auseinanderliegt löschen

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von xenomorph150, 08.07.2009.

  1. #1 xenomorph150, 08.07.2009
    xenomorph150

    xenomorph150 Grünschnabel

    Dabei seit:
    18.06.2009
    Beiträge:
    8
    Zustimmungen:
    0
    Hallo Leute,

    ich habe ein Problem mit einer Logdate.
    Ich prüfe mit einem Skript das ich laufen lasse alle 3 Minuten ob ein System noch online ist. Ich lasse mir folgendes ausgeben:

    z.b:

    09/07/08 13:09:01
    09/07/08 13:12:02
    09/07/08 13:15:01
    09/07/08 13:18:01
    09/07/08 13:21:01
    09/07/08 13:48:01
    09/07/08 13:51:01
    09/07/08 15:15:01
    09/07/08 15:18:01
    09/07/08 15:21:01
    09/07/08 15:24:01

    Jetzt möchte ich aber diese Logdateien nochmal überarbeiten lassen, also sollen alle Einträge bei welcher die Zeit mehr als drei Minuten auseinanderliegen gelöscht werden (3 Minuten Abfrage Rhythmus).
    Dabei sollen aber die erste und die letzte Zeile stehen bleiben, damit ich immer weiß von wann bis wann das Ding funktionierte - und wann es abgeschaltet war.

    So sähe also mein Ergebniss am besten aus:

    09/07/08 13:09:01
    09/07/08 13:21:01
    09/07/08 13:48:01
    09/07/08 13:51:01
    09/07/08 15:15:01
    09/07/08 15:24:01

    Hat jemand eine Idee wie das gehen könnte?
    Ich müsste also erstmal pro Zeile das Datum abtrennen anfangs, dann die Stellen nach dem 2ten Doppelpunkt (der Minutenzähler) mit dem der nächsten Zeile vergleichen ob der 3 Minuten unterschied hat - und wenn ja ihn löschen - wenn DANACH noch einer kommt der 6 Minuten unterschied zu dem Orginal hat....

    ..Hm... Irgendwie ist dieses Verfahren noch nicht optimal o.o'.

    Hat jemand vielleicht eine bessere Idee und auch eine Umsetzung dafür?

    Danke,
    Xeno
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 bytepool, 08.07.2009
    Zuletzt bearbeitet: 08.07.2009
    bytepool

    bytepool Code Monkey

    Dabei seit:
    12.07.2003
    Beiträge:
    791
    Zustimmungen:
    0
    Ort:
    /home/sweden/göteborg
    Hi,

    das macht keinen Sinn. Aber ich vermute, dass du genau das Gegenteil meinst, dass alle Zeilen behalten werden sollen, die einen Interval > 3 haben...

    Aber auch das macht mit deinem Beispiel keinen Sinn:
    Nun gut, ich bin mal davon ausgegangen dass du das meintest, und habe da zum Spass ein kleines Skript fuer geschrieben. Einfacher ginge es aber wohl in Perl.

    Code:
    #!/bin/bash
    
    out_file="filtered.txt"
    in_file="logs.txt"
    
    function parse_new_line
    {
        date="$(echo $line | awk -F' ' '{print $1}')"
        time="$(echo $line | awk -F' ' '{print $2}')"
    
        hours="$(echo $time | awk -F':' '{print $1}')"
        minutes="$(echo $time | awk -F':' '{print $2}')"
        seconds="$(echo $time | awk -F':' '{print $3}')"
    
        hours=${hours#0}
        minutes=${minutes#0}
        seconds=${seconds#0}
    }
    
    function set_old
    {
        old_line="$line"
        old_date="$date"
        old_time="$time"
    
        old_hours="${hours}"
        old_minutes="${minutes}"
        old_seconds="${seconds}"
    }
    
    function add_line
    {
        echo $line #>> $out_file
    }
    
    read line < $in_file
    add_line
    
    parse_new_line
    set_old
    
    while read line; do
        parse_new_line
    
        if [ ${hours} -eq ${old_hours} ]; then
            next_interval=$((old_minutes + 3))
    
            if [ $minutes -gt $next_interval ]; then
                add_line
            fi
        else
            add_line
        fi
    
        set_old
    done < $in_file
    
    line=$(tail -n1 $in_file)
    add_line
    
    Dabei wird jetzt weder das Datum beachtet, noch Stundenueberlaeufe. Um das Skript wirklich perfekt zu machen, muesstest du noch eine ganze Menge kleiner if Abfragen hinzufuegen.

    Edit:
    Ausserdem sollte man beachten, dass ich das jetzt so auf die Schnelle geschrieben hab, und das Skript sicherlich keinen Schoenheitswettbewerb gewinnen wird. Variablennamen, Konsistenz, etc. kann alles noch besser.

    mfg,
    bytepool
     
  4. #3 xenomorph150, 09.07.2009
    xenomorph150

    xenomorph150 Grünschnabel

    Dabei seit:
    18.06.2009
    Beiträge:
    8
    Zustimmungen:
    0
    Hallo bytepool,

    tut mir leid ich glaube wir haben ein wenig aneinander vorbei geredet.
    Hier z.b. ein neuer Log:

    09/07/09 08:57:01
    09/07/09 09:00:02
    09/07/09 09:03:02
    09/07/09 09:06:02
    09/07/09 09:09:02
    09/07/09 09:12:02
    09/07/09 09:15:02
    09/07/09 09:18:02
    09/07/09 09:21:02
    09/07/09 09:24:03
    09/07/09 09:27:02
    09/07/09 09:30:01
    09/07/09 09:33:03
    09/07/09 09:36:02
    09/07/09 09:39:02
    09/07/09 09:42:03
    09/07/09 09:45:05
    09/07/09 09:48:02
    09/07/09 09:51:05
    09/07/09 09:54:03
    09/07/09 09:57:02
    09/07/09 10:09:03
    09/07/09 10:12:03
    09/07/09 10:15:02
    09/07/09 10:18:02
    09/07/09 10:21:03
    09/07/09 10:24:03
    09/07/09 10:27:02
    09/07/09 10:30:07
    09/07/09 10:33:03
    09/07/09 10:36:05
    09/07/09 10:39:03
    09/07/09 10:42:02
    09/07/09 10:45:05
    09/07/09 10:48:03
    09/07/09 10:51:02
    09/07/09 10:54:02
    09/07/09 10:57:05
    09/07/09 11:00:04
    09/07/09 11:03:05
    09/07/09 11:06:02
    09/07/09 11:33:04
    09/07/09 11:36:02
    09/07/09 11:39:03
    09/07/09 11:42:02
    09/07/09 11:45:03
    09/07/09 11:48:02
    09/07/09 11:51:03
    09/07/09 11:54:02
    09/07/09 11:57:03
    09/07/09 12:00:02
    09/07/09 12:03:02
    09/07/09 12:06:04
    09/07/09 12:09:04
    09/07/09 12:12:03
    09/07/09 12:15:03
    09/07/09 12:18:02
    09/07/09 12:21:02
    09/07/09 12:24:03
    09/07/09 12:27:02
    09/07/09 12:30:02
    09/07/09 12:33:04
    09/07/09 12:36:02

    Es sollen IMMER die "Anfangszeit" und die "Endzeit" ausgegeben werden hintereinander - oder sogar so: "Anfangszeit - Endzeit".
    Definiert sind Anfangszeit und Endzeit als Punkte die nicht länger als 3-5 Minuten auseinanderliegen (ich sag mal 5 als Toleranz wenn schwere Netzwerklast vorliegt, man sieht ja dass er mal eine Sekunde oder so mal hin und wieder mehr braucht).

    In dem fall wäre aus der Tabelle oben also als Ergebnis:

    09/07/09 08:57:01
    09/07/09 09:57:02
    09/07/09 10:09:03
    09/07/09 11:06:02
    09/07/09 11:33:04
    09/07/09 12:36:02

    oder sogar wenns möglich ist:

    09/07/09 08:57:01 - 09/07/09 09:57:02
    09/07/09 10:09:03 - 09/07/09 11:06:02
    09/07/09 11:33:04 - 09/07/09 12:36:02

    diese Sachen ausgegeben.
    Damit ich immer weiß von wann bis wann das System funktionierte.

    Ist sowas möglich? Vielen Dank schon mal für deine Hilfe!


    Gruß,

    Nico
     
  5. #4 bytepool, 09.07.2009
    Zuletzt bearbeitet: 09.07.2009
    bytepool

    bytepool Code Monkey

    Dabei seit:
    12.07.2003
    Beiträge:
    791
    Zustimmungen:
    0
    Ort:
    /home/sweden/göteborg
    Hi,

    an deinen Erklaerungskuensten musst du wirklich noch arbeiten, das ist immer noch Falsch. Wenn ich das so anwende wie du es schreibst, bekommst du jede Menge kleine 3 Minuten Intervalle; die Logdatei wuerde sich kaum veraendern.

    Mit dem Hinweis auf Anfangszeit und Endzeit, zusammen mit den Beispielen, bin ich jetzt aber, denke ich, dahinter gestiegen was du eigentlich genau willst.

    Um dein Problem mal korrekt zu formulieren:

    Anhand von einer Logdatei sollen "uptime" Intervalle eines bestimmten Servers gefunden werden. In Intervallen von x Minuten gibt es einen Logeintrag. Wenn ein Logeintrag ausgelassen wird, definiert dies das Ende des gesuchten "uptime" Intervalls, wovon jeweils nur die Anfangszeit und die Endzeit gespeichert werden soll. Der folgende Logeintrag beginnt das naechste "uptime" Intervall.

    Richtig?

    Was passt dir an dem Skript jetzt nicht? Ist doch eine prima Vorlage, die Anpassung an deine Vorgaben erfordert noch ein bisschen eigene Arbeit, ist aber eigentlich ziemlich einfach.
    Im Grunde musst du nur noch eine Zeile hinzufuegen, und dann noch ein paar Randbedingungen ueberpruefen.

    Das darfst du aber selbst machen, das ist mir zu langweilig. ;)

    Nebenbei, fuer die Auflistung der Beispiele koenntest du Code-Bloecke benutzen, das macht deine Posts lesbarer.

    Edit:
    Im uebrigen ist die saubere Formulierung des Problems bereits der erste Schritt zur Problemloesung. Wenn die Problemstellung von Anfang an wie von mir formuliert gewesen waere, wuerde mein Skript ganz anders aussehen; deutlich klarer und strukturierter, weil die Konzepte klar waeren.

    Edit2:
    Wie hat Daniel Jackson das mal so schoen in Software Abstractions (MIT Press) formuliert?
    mfg,
    bytepool
     
  6. #5 xenomorph150, 15.07.2009
    Zuletzt bearbeitet: 16.07.2009
    xenomorph150

    xenomorph150 Grünschnabel

    Dabei seit:
    18.06.2009
    Beiträge:
    8
    Zustimmungen:
    0
    Hi bytepool,

    Verzeihung für die Unanehmlichkeiten, ich denke wir haben irgendwie aneinander vorbei geredet. Ich habe nach einigem Nachdenken eine eigene Lösung für das Problem gefunden und poste sie hiermit nun für den Fall das jemanden das helfen würde.

    mk_log.sh
    Code:
    #! /bin/sh
    tr -d '\015\032' < $1 | sed -e "/^ *$/d" > $1_tr  # Win <> Lin Uebersetzung und Leerzeichen Entfernung
    gawk -f mk_log_primer.awk $1_tr > $1_primer       # Log Primer trennt Datum und Uhrzeit auf
    gawk -f mk_log_coder.awk $1_primer > $1_cod       # Log Coder erzeugt fertige Logfile
    
    rm $1_tr
    rm $1_primer

    mk_log_primer.awk
    Code:
    #14.07.09 mk_log_primer.awk
    
    #------------------------------------------------------------------------------
    BEGIN{ idx=1; FS=" "}
    #------------------------------------------------------------------------------
    {
      datum[idx]=$1
      zeit[idx]=$2
      idx++
    }
    #------------------------------------------------------------------------------
    END{ 
    i=1
    
    do 
    {
    	printf "%s\n",zeit[i]
           i++
    } 
    while (i < idx)
    }
    #------------------------------------------------------------------------------
    
    
    #------------------------------------------------------------------------------

    mk_log_coder.awk
    Code:
    #15.07.09 mk_log_coder.awk
    
    #------------------------------------------------------------------------------
    BEGIN{ idx=1; FS=":"}
    #------------------------------------------------------------------------------
    {
      stunden[idx]=$1
      minuten[idx]=$2
      sekunden[idx]=$3
      idx++
    
    }
    #------------------------------------------------------------------------------
    END{ 
    i=1
    	printf "%s%s%s%s%s%s","Anfang: ", stunden[i],":",minuten[i],":",sekunden[i] 
    
    do 
    {
    	diffstd=stunden[i+1]-stunden[i]
    
    	if (diffstd==0)
    	{
    	differenz=minuten[i+1]-minuten[i]
    
    
    	if (differenz>3)
    	{
    		printf "%s%s%s%s%s%s\n"," - Ende: ", stunden[i],":",minuten[i],":",sekunden[i] 
    		printf "%s%s%s%s%s%s","Anfang: ", stunden[i+1],":",minuten[i+1],":",sekunden[i+1]
    	}
    	else
    	{
    		if (differenz<0)
    		{
    			printf "%s%s","Differenz < 0", " "
    		}
    	}
    	}
    
    	if (diffstd>0)
    	{
    	differenz=minuten[i+1]-minuten[i]
    	differenz=(diffstd*60)+differenz
    
    	if (differenz>3)
    	{
    		printf "%s%s%s%s%s%s\n"," - Ende: ", stunden[i],":",minuten[i],":",sekunden[i] 
    		printf "%s%s%s%s%s%s","Anfang: ", stunden[i+1],":",minuten[i+1],":",sekunden[i+1]
    	}
    	else
    	{
    		if (differenz<0)
    		{
    			printf "%s%s","Differenz < 0", " "
    		}
    	}
    	}
    	
    	if (diffstd<0)
    	{
    		printf "%s%s%s%s%s%s\n"," - Ende: ", stunden[i],":",minuten[i],":",sekunden[i]
    	}
    
           i++
    } 
    while (i < idx)
    }
    #------------------------------------------------------------------------------
    
    
    #------------------------------------------------------------------------------
    



    Beispielsdatei:
    Code:
    09/07/08 12:54:01
    09/07/08 12:57:01
    09/07/08 13:00:01
    09/07/08 13:03:01
    09/07/08 13:05:01
    09/07/08 13:06:01
    09/07/08 13:09:01
    09/07/08 13:36:01
    09/07/08 13:39:01
    09/07/08 13:42:01
    09/07/08 13:48:01
    09/07/08 13:51:01
    09/07/08 13:54:01
    09/07/08 14:18:01
    
    09/07/08 14:33:01
    09/07/08 14:36:01
    

    Ausgabe:
    Code:
    Anfang: 12:54:01 - Ende: 13:09:01
    Anfang: 13:36:01 - Ende: 13:42:01
    Anfang: 13:48:01 - Ende: 13:54:01
    Anfang: 14:18:01 - Ende: 14:18:01
    Anfang: 14:33:01 - Ende: 14:36:01
    


    Grüße,

    Nico


    EDIT: Noch ein Fehler im Code beseitigt ^^
     
Thema:

awk/sed Zeilen bei der Uhrzeit 3 Minuten auseinanderliegt löschen

Die Seite wird geladen...

awk/sed Zeilen bei der Uhrzeit 3 Minuten auseinanderliegt löschen - Ähnliche Themen

  1. Mit awk/sed letztes Feld entfernen - wie?

    Mit awk/sed letztes Feld entfernen - wie?: Ich muss aus einer Liste mit Updates, das Architekturkürzel im letzten Feld entfernen (inkl. Punkt) kann ich das mit awk oder sed irgendwie...
  2. 2 Zeilen aus einer txt auslesen

    2 Zeilen aus einer txt auslesen: Hallo Leute, ich habe eine Datei die immer aus zwei zusammenhängenden Zeilen besteht, als Beispiel: DE0006231004 # 15,04 Infineon DE0005785604...
  3. Zeichen an Zeilenanfang für bestimmten Zeilenbereich einfügen

    Zeichen an Zeilenanfang für bestimmten Zeilenbereich einfügen: Hallo, ich würde gerne in einem Textdokument, z.B. von Zeile 10 - 18, an den Zeilenanfang ein # einfügen. Habe mir schon diverse Seiten zu SED...
  4. Textdatei zeilenweise in durchnummerierte Variablen schreiben

    Textdatei zeilenweise in durchnummerierte Variablen schreiben: Hi Leute, ich versuche folgendes Problem zu lösen. Ich möchte eine Textdatei einlesen und den Inhalt jeder Zeile in immer eine neue Variable...
  5. .cfg Datei Analysieren und Zeilen Stellenweise abändern

    .cfg Datei Analysieren und Zeilen Stellenweise abändern: Hallo allesamt :) ich hab ein kleines Problem. Ich will mittels eines Shell Skriptes in einer Datei die Namensgebung einiger Geräte ändern. Ich...