将awk变量传递给strftime

时间:2016-03-17 12:55:44

标签: bash csv awk gawk

我有一个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=$2" "$3" UTC"} {print strftime("%F %H.%M.%S %Z", a)}' <csv-file>

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

2 个答案:

答案 0 :(得分:1)

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

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

2016-02-01 13.52.00 EST

答案 1 :(得分:1)

首先,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$0 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)非常重要。