ログファイルのタイムスタンプを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コマンドのデバッグ方法は本当にわかりません。タイムゾーンのスラッシュが気に入らないのではないかと思いますが、それは推測にすぎません。
日付が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
_で異なることに注意してください。ロンドンが_-1
_であり、UTCが_0
_であるため、1時間の差。
形式が非常に厳密であることを理解してください。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を使用して日付からすべての値を取得できます(awkへの1回の呼び出しで異なるFSに注意してください(技術的に言えば、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()
は、TZ時間、さらにはOlsonデータベースからの値を理解できません。
@Isaacは正しい軌道にあり、入力に対してはおそらくうまくいくので、彼を受け入れられた回答として残してください。ただし、入力が予期される[date+time]
文字列で開始されない場合をキャッチするには、このようにします、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出力が入力ファイルを上書きすることを心配せずにawk 'script' file > tmp && mv tmp file
のようなスクリプトを記述できます。そうでない場合は、awk 'script' file
の結果をテストできます。