.titleBar { margin-bottom: 5px!important; }

[gelöst] Datumsformat ändern

Dieses Thema im Forum "Freetz" wurde erstellt von freddy4711, 16 Dez. 2008.

  1. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Hi...

    ich bin gerade dabei, ein Shell-Script zur Auswertung der Logfiles zu schreiben. Habe das Script auch auf einem Ubuntu-Rechner mit einer Bash-Shell getestet. Da hat es einwandfrei funktioniert.

    Nun habe ich es auf der Box in die debug.cfg eingetragen. Nach 'nem Reboot war im /var/tmp/ mein Skript zu finden und ließ sich auch ausführen.

    Nun aber mein Problem:
    Ich möchte das Datum des Logfiles Zeile für Zeile in einen UNIX-Timestamp umwandeln, um damit besser zu Arbeiten.

    Ich habe eine while-Schleife, welche das Logfile zeilenweise bis zum Ende durchläuft.

    Zuerst separiere ich das das Datum:
    Code:
    dat=$(echo $line|cut -d" " -f1-3)
    Anschließend wandle ich das Datum mittels der DATE-Funktion in den UNIX-Timestamp um:
    Code:
    sec=$(date -d"$dat" +%s )
    und gebe das Ganze wieder auf die Konsole aus...
    Code:
    echo "$line" |sed s/^"$dat"/$sec/
    Leider funktioniert die Umrechnung ded Datums mit der DATE-Funktion auf der Box nicht.

    Ich bekomme in jeder Zeile folgende Fehlermeldung:
    Code:
    date: invalid date 'Dec 16 14:XX:XX'
    Kann mir jemand helfen?

    Gruß Andreas
     
  2. RalfFriedl

    RalfFriedl IPPF-Urgestein

    Registriert seit:
    22 Apr. 2007
    Beiträge:
    12,343
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    "date --help" zeigt die Datumsformate an, die das date der Busybox unterstützt.
    Das normale date-Kommando unterstützt anscheinend einiges mehr, dafür muß man suchen, bis man die Dokumentation dafür findet.

    Da die Busybox auf kleinen Platzverbrauch ausgelegt ist, kann ich nachvollziehen, daß nicht alle Formate unterstützt werden.
     
  3. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Das Datumsformat der Busybox DATE-Funktion ist sehr eingeschränkt...

    ist es irgendwie möglich, die DATE-Funktion der GNU-Coreutils zu implementieren?

    Gruß Andreas
     
  4. RalfFriedl

    RalfFriedl IPPF-Urgestein

    Registriert seit:
    22 Apr. 2007
    Beiträge:
    12,343
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Ja klar, die Quellen der GNU Coreutils sind frei zugänglich.
     
  5. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Leider kenne ich mich damit noch nicht so aus.

    Aber was muss ich tun, um die Date-Funktion aus GNU-Coreutils in die Freetz-Firmware einzubauen.

    Gruß Andreas
     
  6. olistudent

    olistudent IPPF-Urgestein

    Registriert seit:
    19 Okt. 2004
    Beiträge:
    14,756
    Zustimmungen:
    1
    Punkte für Erfolge:
    0
    Beruf:
    Softwareentwickler
    Ort:
    Kaiserslautern
    #6 olistudent, 16 Dez. 2008
    Zuletzt bearbeitet: 16 Dez. 2008
    Schonmal danach gegoogelt?
    Ich bin auf sowas gestoßen:
    Code:
    awk 'BEGIN { print strftime("%c", 1141421607); exit }'
    MfG Oliver

    edit: Ups. Wenn man keine Ahnung hat einfach mal Fresse halt. :mrgreen:
     
  7. RalfFriedl

    RalfFriedl IPPF-Urgestein

    Registriert seit:
    22 Apr. 2007
    Beiträge:
    12,343
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Das ist die umgekehrte Richtung, Timestamp nach lesbarem Datum.

    In der C-Library gibt es die Funktion strptime, die einen String einliest und daraus ein "struct tm" erstellt. Aus diesem kann man dann wiederum mit mktime ein Timestamp erstellen.

    Evtl. sind diese Funktionen auch in awk vorhanden.

    Ansonsten gibt es im freetz Wiki eine Anleitung, um eigene Pakete zu erstellen. Für die meisten Pakete (die Gnu Utilities gehören vermutlich dazu) ist das Cross-Compilieren relativ einfach.
     
  8. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Habe grad einmal nachgeschaut, aber die Funktion strptime() ist nicht in awk verfügbar.

    Ich werde noch ein wenig im Netz suchen. Falls ich nichts mehr anderes finde, werde ich mich ans Einbauen der GNU-Coreutils machen.

    Spätestens dann werde ich mich wieder melden :rolleyes:

    Gruß Andreas
     
  9. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Hi...

    hab nochmal ein bisschen rumgebastelt - und habe nun folgende Lösung gefunden. Ist wahrscheinlich nicht die Beste, aber funktionieren tut sie...

    Mir gefällt nur nicht, wie ich die Monatsangaben umrechne...aber leider gibt es für die Freetz-Shell (ash) keine Möglichkeit, Arrays einzubauen? Oder bin ich da falsch informiert? Denn gefunden habe ich im Netz nix...

    Hier mein Script:
    Code:
    #!/bin/sh
    
    # date2timestamp.sh - Datumsumwandlung für die Busybox-Date-Funktion
    
    cat - | while read line
    do
      datum=$(echo $line|cut -d" " -f1-3)
      monthName=$(echo $line|cut -d" " -f1)
      day=$(echo $line|cut -d" " -f2)  
      hour=$(echo $line|cut -d" " -f3|cut -d":" -f1) 
      min=$(echo $line|cut -d" " -f3|cut -d":" -f2) 
      sec=$(echo $line|cut -d" " -f3|cut -d":" -f3)
    
      case $monthName in
        Jan ) month="1";;
        Feb ) month="2";;
        Mar ) month="3";;
        Apr ) month="4";;
        May ) month="5";;  
        Jun ) month="6";;  
        Jul ) month="7";;
        Aug ) month="8";;
        Sep ) month="9";;
        Oct ) month="10";;
        Nov ) month="11";;
        Dec ) month="12";;
      esac
        
      timestamp=`date -d"$month$day$hour$min.$sec"`
      echo "$line" |sed s/^"$dat"/$timestamp/
    done
    Gruß Andreas
     
  10. RalfFriedl

    RalfFriedl IPPF-Urgestein

    Registriert seit:
    22 Apr. 2007
    Beiträge:
    12,343
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Zunächst einmal könntest Du die Aufteilung machen, ohne so viele Unterprozesse zu starten. Jede Konstruktion mit $() startet eine sub-Shell, mit in Deinem Beispiel jeweils 2-3 Prozessen, und das etliche Male für jede einzelne Zeile.
    Das geht effizienter mit:
    Code:
    while IFS=' :' read monthName day hour min sec line; do
    
    Auch das "cat -" ist unnötig.

    Das case kannst Du evtl. umgehen, indem Du eine Zuweisung an an Variablen machst, ungefähr so:
    Code:
    mon_Jan=1
    mon_Feb=2
    ...
    mon_Dez=12
    eval mon=\$mon_$monthName
    
    Die Zuweisung der 12 Werte kann dabei auch vor der Schleife stehen.
    Ob es effizienter ist als das case, weiß ich auch nicht.

    Andererseits, wenn Dir Effizienz wichtig ist (je nach Größe der Datei), dann wären einige Zeilen in C sicher besser.
     
  11. hermann72pb

    hermann72pb IPPF-Promi

    Registriert seit:
    6 Nov. 2005
    Beiträge:
    3,564
    Zustimmungen:
    0
    Punkte für Erfolge:
    36
    Ich habe die Aufgabe leider nicht ganz verstanden. Was ist der Ist-Zustand und was ist Soll-Zustand vom Datumsformat? Was soll gemacht werden? Ein Datum in einer Datei verändert werden?
    Ich würde aus meinem Bauchgefühl sed dafür nehmen. Busybox-sed ist zwar auch etwas eigenartig, aber damit geht schon einiges. Zwar bekommt man damit keinen sed-Einzeiler, aber Konstrukte wie in etwa:
    Code:
    sed -e "s/Jan/01/g;s/Feb/02/g;"
    
    können schon weiter helfen. Man kann mit sed auch gut die Reihenfolge ändern, z.B. "2. Jan" anstatt "Jan 2" überall schreiben. Und mit busybox-sed geht sowas definitiv.

    Für grep/sed-Manipulationen (busybox grep geht übrigens auch, und sogar mit -e!) sollte man allerdings etwas besser Kontext kennen, sprich den Inhalt der Logdatei, um die Suche besser einzugrenzen. Z.B. wenn das Datum am Anfang jeder Zeile steht, erleichtert es die Suche enorm.

    Deswegen poste hier am besten 2-3 Zeilen als Beispiel und was du daraus machen willst.

    MfG
     
  12. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Hi...

    vom Format her sieht mein Logfile ja so aus:
    Code:
    Dec 18 00:00:26 Speedport_W_701V_33-04-56 ...
    Dec 18 00:00:26 Speedport_W_701V_33-04-56 ...
    Dec 18 00:09:55 Speedport_W_701V_33-04-56 ...
    Dec 18 00:10:01 Speedport_W_701V_33-04-56 ...
    
    Nun möchte ich für eine Logfile-Analyse das Datum in einen UNIX-Timestamp umwandeln, da dieser einfacher zu Handhaben ist...
    Code:
    1229555426 Speedport_W_701V_33-04-56 ...
    1229555426 Speedport_W_701V_33-04-56 ...
    1229555401 Speedport_W_701V_33-04-56 ...
    1229555395 Speedport_W_701V_33-04-56 ...
    
    Mein Script, welches ich mit Hilfe der Tips von RalfFriedl angepasst habe, sieht jetzt so aus:
    Code:
    #!/bin/sh
    #date2timestamp.sh - Datumsumwandlung fuer die Busybox-Date-Funktion
    
    month_Jan="1"
    month_Feb="2"
    month_Mar="3"
    month_Apr="4"
    month_May="5"
    month_Jun="6"
    month_Jul="7"
    month_Aug="8"
    month_Sep="9"
    month_Oct="10"
    month_Nov="11"
    month_Dec="12"
    
    while IFS=' :' read monthName day hour min sec line;
    do
      eval month=\$month_$monthName
    
      timestamp=`date -d"$month$day$hour$min.$sec" +%s`
      echo "$line" |sed s/^"$datum"/$timestamp/
    done
    
    Das Script rufe ich wie folgt auf:
    Code:
    logread | grep <irgendetwas> | /var/tmp/date2timetamp.sh
    
    Es funktioniert auch soweit. Bis auf eine kleine Sache; beim Ersetzen des Alten Datums durch den generierten Timestamp wird das Leerzeichen zum Logtext entfernt. Und ich habe es bis jetzt nicht hinbekommen, dieses wieder einzufügen.
    Code:
    1229555395Speedport_W_701V_33-04-56 ...
    
    Gruß Andreas
     
  13. RalfFriedl

    RalfFriedl IPPF-Urgestein

    Registriert seit:
    22 Apr. 2007
    Beiträge:
    12,343
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Bist Du sicher, daß Dein Skript genau so aussieht?
    Speziell diese Zeile ist seltsam, weil $datum vorher im Skript nicht definiert wird.
    Ok, mir ist klar, was passiert. $datum ist leer, also wird /^/$timestamp/ ersetzt, also $timestamp am Anfang der Zeile eingefügt. Was Du nicht beachtet hast, ist, daß durch das read der Wert von line nicht die komplette Zeile ist, sonder nur die Meldung selbst, ohne das Datum.

    Ersetze diese Zeile durch
    Code:
      echo "$timestamp $line"
    
    dann sollte es gehen.
     
  14. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Hi...

    alles klar. So klappt es...

    Habe mich auch schon gefragt, warum das mit der Variable $datum noch funktioniert...


    Nun habe ich noch ne Frage unabhängig von diesem Problem...

    Wie kann ich den Hostnamen der Box ändern?

    IST:
    Code:
    Speedport_W_701V_33-04-56
    
    SOLL (z.B.):
    Code:
    router
    
    Dankeschön...

    Gruß Andreas
     
  15. jojo-schmitz

    jojo-schmitz Aktives Mitglied

    Registriert seit:
    6 Mai 2006
    Beiträge:
    2,472
    Zustimmungen:
    3
    Punkte für Erfolge:
    38
    Beruf:
    Informatiker
    Ort:
    Düsseldorf
    Code:
    echo "$timestamp $line" | sed 's/Speedport_W_701V_33-04-56/router/'
     
  16. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    Hi...

    nein...ich meine wirklich den Hostnamen der Box ändern.

    Gruß Andreas
     
  17. jojo-schmitz

    jojo-schmitz Aktives Mitglied

    Registriert seit:
    6 Mai 2006
    Beiträge:
    2,472
    Zustimmungen:
    3
    Punkte für Erfolge:
    38
    Beruf:
    Informatiker
    Ort:
    Düsseldorf
    Code:
    hostname router
    Das Leben kann sooo einfach sein :cool:
     
  18. freddy4711

    freddy4711 Neuer User

    Registriert seit:
    7 Juli 2007
    Beiträge:
    155
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Beruf:
    Student
    Ort:
    Karlsruhe
    ok...manchmal sieht man vor lauter Bäumen den Wald nicht mehr...:rolleyes:

    Danke...

    Gruß Andreas