Konvertieren / Ersetzen der Zeit von Epochen-Millisekunden in vom Menschen lesbares Datum in Protokolldateien

Dec 05 2020

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

4 thanasisp Dec 05 2020 at 22:13

Wenn Sie ein Shell-Skript verwenden, das zeilenweise liest, oder ein awkSkript, 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
2 terdon Dec 05 2020 at 22:14

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 strftimeFunktion konvertiert den Zeitstempel in ein Datum. Da Ihre in Millisekunden angegeben ist, sprintfkonvertieren wir diese in Sekunden. Das Finale 1;weist nur gawkan, 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 TZVariable 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