Konvertieren / Ersetzen der Zeit von Epochen-Millisekunden in vom Menschen lesbares Datum in Protokolldateien
Ich habe eine Protokolldatei mit der folgenden Struktur
Beispiel:
1522693524403 entity1,sometext
1522693541466 entity2,sometext
1522693547273 entity1,sometext
...
Jetzt möchte ich die Zeit von Epise Millisekunden bis DD.MM.YYYY HH: MM: SS in allen Protokolldateien durch einen Bash-Befehl auf einem Debian-System ersetzen.
Ich habe verschiedene Lösungen ausprobiert, die hier und auf anderen Websites bereitgestellt wurden, aber es hat bei mir nicht wirklich funktioniert.
Kann mir bitte jemand helfen?
Prost
Fastboot
Antworten
Wenn Sie ein Shell-Skript verwenden, das zeilenweise liest, oder ein awk
Skript, das ein System aufruft date
, sind die Prozesse sehr langsam und zu langsam. Sie müssen ein einfaches awk-, Perl-, Python- oder ein anderes Skript verwenden. Alle Sprachen verfügen über Standard-Datums- / Uhrzeitfunktionen für die Konvertierung zwischen Formaten.
Hier und hier sind einige gute Referenzen. Wenn Sie GNU- awk
Zeitfunktionen verwenden möchten und strftime()
für Ihren Fall nur den Epochen-Teilstring ohne die Millisekunden auswählen müssen:
$ awk '{$1 = strftime("%F %T", substr($1,1,10))} 1' file
2018-04-02 21:25:24 entity1,sometext
2018-04-02 21:25:41 entity2,sometext
2018-04-02 21:25:47 entity1,sometext
Oder um die Millisekunden zusammen zu drucken:
$ awk '{$1 = strftime("%F %T", substr($1,1,10)) "." substr($1,11)} 1' file
2018-04-02 21:25:24.403 entity1,sometext
2018-04-02 21:25:41.466 entity2,sometext
2018-04-02 21:25:47.273 entity1,sometext
Oder um das Tag-Monat-Jahr-Format auszudrucken:
$ awk '{$1 = strftime("%d-%m-%Y %T", substr($1,1,10))} 1' file
02-04-2018 21:25:24 entity1,sometext
02-04-2018 21:25:41 entity2,sometext
02-04-2018 21:25:47 entity1,sometext
Dies können Sie nicht mit einem bash-Befehl tun. Sie benötigen ein externes Programm, da bash keine Gleitkomma-Berechnungen durchführen und keine Daten verarbeiten kann. Ich vermute, Sie haben nur "auf der Kommandozeile" gemeint, und Sie benötigen eigentlich keine reine Bash-Lösung. Mit dieser Annahme ist hier eine gawk
(GNU awk) Lösung:
$ gawk '{$1=strftime("%d.%m.%Y %H:%m:%S",sprintf("%.3f", $1 /1000))}1;' file
02.04.2018 19:04:24 entity1,sometext
02.04.2018 19:04:41 entity2,sometext
02.04.2018 19:04:47 entity1,sometext
Die strftime
Funktion konvertiert den Zeitstempel in ein Datum. Da Ihre in Millisekunden angegeben ist, sprintf
konvertieren wir diese in Sekunden. Das Finale 1;
weist nur gawk
an, die Zeile zu drucken, nachdem wir den neuen Wert zugewiesen haben $1
(das erste Feld).
Denken Sie daran, dass die Ausgabe von Ihrer Zeitzone abhängt. Das Obige wurde beispielsweise auf einer Maschine ausgeführt, die auf die GMT-Zeitzone eingestellt war. Aus diesem Grund unterscheiden sich meine Zahlen von denen in der Antwort von @ thanasisp, die vermutlich in einer anderen Zeitzone ausgeführt wurde. Sie können dies steuern und die Ausgabe ändern, indem Sie die TZ
Variable beim Ausführen des Befehls festlegen. Vergleichen Sie zum Beispiel Folgendes:
$ gawk '{$1=strftime("%d.%m.%Y %H:%m:%d.%S",sprintf("%.3f", $1 /1000))}1;' file
02.04.2018 19:04:02.24 entity1,sometext
02.04.2018 19:04:02.41 entity2,sometext
02.04.2018 19:04:02.47 entity1,sometext
dazu:
$ TZ=America/Los_Angeles gawk '{$1=strftime("%d.%m.%Y %H:%m:%d.%S",sprintf("%.3f", $1 /1000))}1;' file
02.04.2018 11:04:02.24 entity1,sometext
02.04.2018 11:04:02.41 entity2,sometext
02.04.2018 11:04:02.47 entity1,sometext
Oder dieses:
$ TZ=Asia/Tokyo gawk '{$1=strftime("%d.%m.%Y %H:%m:%d.%S",sprintf("%.3f", $1 /1000))}1;' file
03.04.2018 03:04:03.24 entity1,sometext
03.04.2018 03:04:03.41 entity2,sometext
03.04.2018 03:04:03.47 entity1,sometext