首页 > 解决方案 > 带日期的 awk 从 unix 时间转换为日期

问题描述

如何将 Epoch 时间转换为日期(mac os)并打印两列。

1556453126 20 
1567954567 30 
1567988161 25 
1566992153 40

awk -F';' -v OFS=';' '$1 {cmd="date -d \""$1"\" +%s"; cmd | getline $1; close(cmd)} 1' t.log

strftime 在 mac os 中不起作用

预期的:

2019-03-01 21:00 20
2019-03-02 20:50 30
2019-01-21 21:30 25
2019-08-01 21:30 40

任何可读的日期格式都可以

标签: dateunixawk

解决方案


当你有少量数据时,James Brown的答案是快速且足够好的。

下面我介绍了几种解决方案,您可以根据使用的 awk 使用它们:

Gnu awk:gawk时间函数的各种扩展之一。这个问题的两个有用的时间函数是mktimestrftime

  • strftime(format,timestamp,[utc-flag]):这会将纪元时间timestamp转换为格式化的字符串(与命令的格式相同date)。您可以使用utc-flag指示返回的时间应为 UTC 或本地时区。

GNU awk 手册中的更多信息

$ awk '{$1=strftime("%F %R",$1)}1' data.txt

POSIX awk:如果您没有 GNU awk,但有任何其他 awk,则不能使用这些时间函数,因为它们是 GNU awk 特定的。但是,可以实现它们:

awk '

# Algorithm from "Astronomical Algorithms" By J.Meeus
function strftime_posix(epoch, JD,yyyy,mm,dd,HH,MM,SS,A,B,C,D,E ) {
    if (epoch < 0 ) return "0000 00 00 00 00 00.000000"
    JD=epoch; SS=JD%60; JD-=SS; JD/=60; MM=JD%60;
    JD-=MM; JD/=60; HH=JD%24; JD-=HH; JD/=24;
    JD+=2440588
    A=int((JD - 1867216.25)/(36524.25))
    A=JD+1+A-int(A/4)
    B=A+1524; C=int((B-122.1)/365.25); D=int(365.25*C); E=int((B-D)/30.6001)
    dd=B-D-int(30.6001*E)
    mm = E < 14 ? E-1 : E - 13
    yyyy=mm>2?C-4716:C-4715
    return sprintf("%0.4d-%0.2d-%0.2d %0.2d:%0.2d",yyyy,mm,dd,HH,MM)
}

{ $1 = strftime_posix($1) }1' data.txt

请注意,这不适用于您的时区,并将返回 UTC 值。


推荐阅读