Konwertuj / zamień czas z milisekund epoki na datę czytelną dla człowieka w plikach dziennika
Mam plik dziennika o następującej strukturze
Przykład:
1522693524403 entity1,sometext
1522693541466 entity2,sometext
1522693547273 entity1,sometext
...
Teraz chciałbym zamienić czas z milisekund epoki na DD.MM.RRRR GG: MM: SS we wszystkich plikach dziennika poleceniem bash w systemie Debian.
Wypróbowałem różne rozwiązania dostarczone tutaj i na innych stronach internetowych, ale tak naprawdę nie działały.
Czy ktoś może mi pomóc, proszę?
Twoje zdrowie
fastboot
Odpowiedzi
Jeśli używasz skryptu powłoki czytającego wiersz po wierszu lub awk
systemu wywołującego skrypt date
, byłoby to bardzo powolne, zbyt wiele procesów. Musisz użyć prostego skryptu awk, Perl, Python lub czegokolwiek. Wszystkie języki mają standardowe funkcje daty i godziny do konwersji między formatami.
Tutaj i tutaj są dobre referencje. Jeśli chcesz korzystać z awk
funkcji czasu GNU i strftime()
, wszystko, czego potrzebujesz w swoim przypadku, to wybrać podciąg epoki z wyłączeniem milisekund:
$ 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
Lub wydrukować razem milisekundy:
$ 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
Lub wydrukować format dzień-miesiąc-rok:
$ 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
To nie jest coś, co możesz zrobić za pomocą polecenia bash, potrzebujesz zewnętrznego programu, ponieważ bash nie może wykonywać obliczeń zmiennoprzecinkowych i nie obsługuje dat. Podejrzewam, że miałeś na myśli po prostu „w wierszu poleceń” i tak naprawdę nie potrzebujesz czystego rozwiązania bash. Przy takim założeniu gawk
mamy rozwiązanie (GNU awk):
$ 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
strftime
Konwertuje znacznik czasu do tej pory. Ponieważ twój jest w milisekundach, używamy go sprintf
do konwersji na sekundy. Ostateczna 1;
po prostu mówi, gawk
aby wydrukować wiersz po przypisaniu nowej wartości do $1
(pierwszego pola).
Pamiętaj, że wynik będzie zależał od Twojej strefy czasowej. Na przykład powyższe zostało uruchomione na komputerze ustawionym na strefę czasową GMT. Dlatego moje liczby różnią się od tych w odpowiedzi @ thanasisp, która prawdopodobnie została uruchomiona w innej strefie czasowej. Możesz kontrolować to i zmienić wyjście, ustawiając TZ
zmienną podczas uruchamiania polecenia. Na przykład porównaj to:
$ 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
do tego:
$ 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
Albo to:
$ 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