将 awk 变量传递给 strftime

Passing awk variable to strftime

我有一个 CSV,其中第 2 列和第 3 列分别是日期和时间(UTC 格式)。

Id,Date,Hour,Name,...
1,2016-02-01,13:52,name1,...
2,2016-02-01,11:02,name2,...
3,2016-01-30,17:43,name3,...
4,2016-01-29,20:07,name4,...
5,2016-01-29,20:05,name5,...
.
.
.

我需要将其转换并合并到德国时间(一般化,CET/CEST)。我首先将第 2 列和第 3 列连接成一个 awk 变量 a,但我无法将其作为第二个参数传递给函数 strftime

TZ="Europe/Berlin" awk 'BEGIN { FS=OFS=","} NR!=1 {a=" "" UTC"} {print strftime("%F %H.%M.%S %Z", a)}' <csv-file>

如何在 strftime 函数中传递 awk 变量 a

awk 日期处理并不像您想象的那么灵活。您不能将任意格式的时间戳传递给 strftime。我会恢复到系统日期 这是一个示例脚本:

$ echo 1,2016-02-01,13:52,name1,... | 
  awk -F, '{cmd = "date -d \""  " "  "\" \"+%F %H.%M.%S %Z\""; cmd | getline d; print d}'

2016-02-01 13.52.00 EST

首先,awk是一个强大的文本处理工具,但是,对于日期和时间,它就不是那么好。

如果您想使用它的 strftime(),您必须提供一个 awk 接受的 timestamp,例如来自 awk 的 systime() or mktime()。但是如果你想做时区转换,mktime()你不能带。因为它会在您当地的时区加载 datespec

更简单的方法是使用外部 gnu date 命令,在那里您可以对日期进行相当多的控制。

我假设用 awk 处理列对你来说不是问题,我只是用日期部分做一个例子:

假设您以某种方式创建了一个字符串:"2016-02-01 13:52 UTC"

echo "2016-02-01 13:52 UTC"|awk -v q='"' 
       '{cmd="TZ=Europe/Berlin date -d"q[=10=] q" +"q"%F %H.%M.%S %Z"q;
        cmd|getline x;
        close(cmd);print x}'

这将得到:

2016-02-01 14.52.00 CET

所以时区被转换了。请注意,getline 管道后面的 close(cmd) 很重要。