使用 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 命令。我懷疑它可能不喜歡時區的斜線,但這只是一個猜測。
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
. 由於倫敦-1
和 UTC 之間存在一 (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 從 date 獲取所有值(請注意,僅一次呼叫 awk(技術上講:GNU awk 或 nawk)的不同 FS 以及由於時間字元串的元素數量不同而使用 split):
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 數據庫中的值。