在AWK中转换日期

时间:2010-01-23 03:02:57

标签: datetime command-line awk

我有一个包含许多文本列的文件,包括Fri Jan 02 18:23行的时间戳,我需要将该日期转换为MM/DD/YYYY HH:MM格式。

我一直在尝试使用带有awk getline的标准`date'工具来进行转换,但我无法弄清楚如何以预期的格式将字段传递给'date'命令(引用“或者,”因为getline也需要用引号括起来的命令字符串。

"date -d '$1 $2 $3 $4' +'%D %H:%M'" | getline var

这样的东西

现在我考虑一下,我想我真正想问的是如何将awk变量嵌入到字符串中。

3 个答案:

答案 0 :(得分:21)

如果您使用gawk,则不需要可以expensive重复调用的外部date

awk '
BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
    }
format = "%m/%d/%Y %H:%M"
}
{
split($4,time,":")
date = (strftime("%Y") " " months[$2] " " $3 " " time[1] " " time[2] " 0")
print strftime(format, mktime(date))
}'

感谢来自this answer的月份数组 ghostdog74

答案 1 :(得分:17)

你可以试试这个。假设您指定的日期在文件

awk '
{
    cmd ="date \"+%m/%d/%Y %H:%M\" -d \""$1" "$2" "$3" "$4"\""
    cmd | getline var
    print var
    close(cmd)
}' file

输出

$ ./shell.sh
01/02/2010 18:23

如果您不使用GNU工具,例如您在Solaris中,请使用nawk

nawk 'BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
   }
   cmd="date +%Y"
   cmd|getline yr
   close(cmd)
}
{
    day=$3
    mth=months[$2]
    print mth"/"day"/"yr" "$4
} ' file

答案 2 :(得分:1)

我遇到了类似的问题,即使用rrdfetch从RRDTool数据库转换日期,但是我更喜欢自Apollo电脑时代以来一直使用的衬垫。

数据如下:

localTemp             rs1Temp             rs2Temp      thermostatMode
1547123400: 5.2788174937e+00 4.7788174937e+00 -8.7777777778e+00 2.0000000000e+00
1547123460: 5.1687014581e+00 4.7777777778e+00 -8.7777777778e+00 2.0000000000e+00

一个班轮:

rrdtool fetch -s -14400 thermostatDaily.rrd MAX | sed s/://g | awk '{print "echo ""\`date -r" $1,"\`" " " $2 }' | sh

结果:

Thu Jan 10 07:25:00 EST 2019 5.3373432378e+00
Thu Jan 10 07:26:00 EST 2019 5.2788174937e+00

从表面上看,这对我来说不是很有效,但是在大多数情况下,即使对于功率非常低的计算机(例如25Mhz NeXT Machines)上的大文件,这种方法也被证明是相当低的开销。是的,Mhz。

Sed删除冒号,awk用于打印其他感兴趣的其他命令,包括仅回显awk变量,而sh或bash执行生成的字符串。

对于方法论,大型文件或流,我仅将前几行作为标题,然后逐步建立一个衬里。扔掉代码。