ログファイル内の時間をエポックミリ秒から人間が読める日付に変換/置換します

Dec 05 2020

次の構造のログファイルがあります

例:

1522693524403 entity1,sometext
1522693541466 entity2,sometext
1522693547273 entity1,sometext
...

ここで、すべてのログファイルのエポックミリ秒からDD.MM.YYYY HH:MM:SSまでの時間をDebianシステムのbashコマンドに置き換えたいと思います。

ここや他のWebサイトで提供されているさまざまなソリューションを試しましたが、実際にはうまくいきませんでした。

誰か助けてくれませんか?

乾杯

fastboot

回答

4 thanasisp Dec 05 2020 at 22:13

行ごとに読み取るシェルスクリプト、またはawkシステムを呼び出すスクリプトを使用すると、date非常に遅くなり、プロセスが多すぎます。単純なawk、Perl、Python、またはその他のスクリプトを使用する必要があります。すべての言語には、フォーマット間の変換のための標準の日時関数があります。

こことここにいくつかの良い参考資料があります。GNUawk 時間関数とを使用strftime()する場合、ケースに必要なのは、ミリ秒を除くエポック部分文字列を選択することだけです。

$ 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

または、ミリ秒を一緒に出力するには:

$ 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

または、日-月-年の形式を印刷するには:

$ 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

これはbashコマンドで実行できることではありません。bashは浮動小数点演算を実行できず、日付を処理できないため、外部プログラムが必要です。ただし、「コマンドラインで」という意味であり、純粋なbashソリューションは実際には必要ありません。その仮定の下で、ここにgawk(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関数は、タイムスタンプを日付に変換します。あなたのものはミリ秒単位なので、私たちはsprintfそれを秒に変換するために使用します。ファイナル1;gawk、新しい値を$1(最初のフィールド)に割り当てた後に行を印刷するように指示するだけです。


出力はタイムゾーンによって異なることに注意してください。たとえば、上記はGMTタイムゾーンに設定されたマシンで実行されました。これが、私の番号が、おそらく別のタイムゾーンで実行された@thanasispの回答の番号と異なる理由です。TZコマンドの実行時に変数を設定することで、これを制御し、出力を変更できます。たとえば、これを比較します。

$ 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

これに:

$ 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

またはこれ:

$ 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