我有一个包含许多文本列的文件,包括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变量嵌入到字符串中。
答案 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执行生成的字符串。
对于方法论,大型文件或流,我仅将前几行作为标题,然后逐步建立一个衬里。扔掉代码。