awkを使用してタイムスタンプを変換すると、日付が正しくありません。

awkを使用してタイムスタンプを変換すると、日付が正しくありません。

ログファイルのタイムスタンプを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時間も理解できません。

おすすめ記事