
ログファイルのタイムスタンプをUnixタイムスタンプに変換する方法を見つけようとしています。これまで私が思いついたコマンドは次のとおりです。
awk -F'[' '{ print $2}' | awk -F']' '{cmd ="date \"+%s\" -d \""$1"\""; cmd | getline var; print var $2; close(cmd)}'
このコマンドは、元のタイムスタンプにUTCがタイムゾーンに含まれている場合、またはタイムゾーンが指定されていない場合に機能します。ただし、タイムゾーンが異なる値の場合は失敗します。たとえば、次のように動作します。
$ entry="[08-May-2020 15:40:32 UTC] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
$ echo "$entry" | awk -F'[' '{ print $2}' | awk -F']' '{cmd="date \"+%s\" -d \""$1"\""; cmd | getline var; print var $2; close(cmd)}'
1588952432 PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
このコマンドは、タイムゾーンが指定されていない場合でも機能します。
$ entry="[08-May-2020 15:40:32] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
$ echo "$entry" | awk -F'[' '{ print $2}' | awk -F']' '{cmd="date \"+%s\" -d \""$1"\""; cmd | getline var; print var $2; close(cmd)}'
1588948832 PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
ただし、Europe/London
タイムゾーンが次の場合は失敗します。
$ entry="[08-May-2020 15:40:32 Europe/London] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
$ echo "$entry" | awk -F'[' '{ print $2}' | awk -F']' '{cmd="date \"+%s\" -d \""$1"\""; cmd | getline var; print var $2; close(cmd)}'
date: invalid date ‘08-May-2020 15:40:32 Europe/London’
PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
awkコマンドをデバッグする方法がわかりません。タイムゾーンのスラッシュは気に入らないかもしれませんが、これは単なる推測です。
答え1
dateがTZ変数を受け取り、それを理解する方法は面倒です。このコマンドの仕組み:
$ date -d 'TZ="UTC" 08-May-2020 15:40:32' +"%s"
1588952432
OlsonデータベースのTZ:
$ date -d 'TZ="Europe/London" 08-May-2020 15:40:32' +"%s"
1588948832
そしてエポック時間が異なることに注意し1588952432
てください1588948832
。ロンドンとUTC-1
の時差が1時間だからです0
。
フォーマットが非常に厳しいことを理解してください。まず、TZ、すべてが一重引用符で囲まれ、TZ値も二重引用符で囲まれています。そして、あまりにも厳しく脆弱です。
したがって、配列に値を設定します(bash、ksh、またはzshと仮定)。
entry=(
"[08-May-2020 15:40:32 UTC] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
"[08-May-2020 15:40:32] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
"[08-May-2020 15:40:32 Europe/London] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
)
その後、awkを使用して日付のすべての値を取得できます。 (FSはawkへの1回の呼び出しで異なり(技術的にはGNU awkまたはnawk)、時間文字列の要素数が異なるため、分割が使用されます。):
printf '%s\n' "${entry[@]}" | awk -F '[][]' '{
n=split($2, val, / /, sep);
cmd=sprintf("date +\"%%s\" -d '\''TZ=\"%s\" %s %s'\''",val[3],val[1],val[2]);
cmd | getline var; close(cmd);
print "["var"]"$3;
}'
[1588952432] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[1588952432] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[1588948832] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
技術的には、ラインは次のようになります。
if ( (rc=(cmd | getline var)) != 1){
print "error on calling the command date ",rc; exit
};
getlineの一部のエラーはキャッチされますが(デフォルトでは、getlineはコマンドから出力を取得できません)、awkはコマンドのエラー番号を報告したりそれに対処することはできません。必要に応じて実行を中止するのはコマンドの責任です。 awkが実行する唯一のこと(エラーかどうか)は、cmdのstderr出力をstderrに直接パイプすることです。したがって、awkのstderrへのコマンドによって発生したすべての説明(またはエラー)を表示できます。必要に応じて確認して解決してください。それ以外の場合、出力ファイルは自動的に破損します。あなたは警告を受けました! 。これがあなたが求めているようです。
いいえ、awkはdatetime()
Olsonデータベースの値だけでなくTZ時間も理解できません。
答え2
[date+time]
@Isaacが正しい方向に向かっています。入力内容に合う可能性があるので、彼の答えを許可された答えとして残してください。しかし、入力が期待される文字列で始まらない場合、または呼び出しがdate
失敗したり失敗したりする場合をキャッチするためにそうします。したがって、getline
メッセージテキストのタイムスタンプの後にある場合は呼び出しが成功し、実行の一部が失敗すると失敗した終了状態で終了します。]
$ cat tst.awk
match($0,/\[[^]]+] /) {
dt = substr($0,RSTART+1,20)
tz = substr($0,RSTART+22,RLENGTH-24)
msg = substr($0,RSTART+RLENGTH)
cmd = sprintf("date -d \047TZ=\"%s\" %s\047 +\047%%s\047", tz, dt)
cmd | getline secs
close(cmd)
}
secs == "" {
printf "%s[%d]: failed to convert: \"%s\"\n", FILENAME, NR, $0 | "cat>&2"
exit 1
}
{ print secs, msg; secs="" }
たとえば、次の入力ファイルがあるとします(最後の2行に注意してください。最初の行はメッセージセクションにあり、2行目は]
間違った日付を持っています)。
$ cat file
[08-May-2020 15:40:32 UTC] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
[08-May-2020 15:40:32] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[08-May-2020 15:40:32 Europe/London] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290
[08-May-2020 15:40:32 Europe/London] PHP Warning: array foo[] is bad, the sky is falling
[08-Bob-2020 15:40:32 Europe/London] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290
$ awk -f tst.awk file
1588952432 PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
1588952432 PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
1588948832 PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290
1588948832 PHP Warning: array foo[] is bad, the sky is falling
date: invalid date ‘TZ="Europe/London" 08-Bob-2020 15:40:32’
file[5]: failed to convert: "[08-Bob-2020 15:40:32 Europe/London] PHP Warning: Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290"
$ echo "$?"
1
失敗した状態で終了する最後の部分が重要であるため、このようなスクリプトを書くことができ、awk 'script' file > tmp && mv tmp file
失敗した場合でも、awk出力が入力ファイルを上書きすることを心配する必要はなく、他の方法で結果をテストできます。awk 'script' file