关于awk:使用GAWK的CSV文件中的Epoch时间戳

Timestamp to Epoch in a CSV file with GAWK

希望使用gawk将人类可读的时间戳转换为csv文件中的epoch/unix时间,以准备加载到mysql db中。

数据示例:

1
{null};2013-11-26;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647

查看第6列,星期二,11月26日12:17 pm,并转换为epoch time进行存储。显示的所有时间都将采用EST格式。我意识到awk是实现这一点的工具,但它似乎不能很好地构造命令。目前有:

1
cat FILE_IN.CSV | awk 'BEGIN {FS=OFS=";"}{$6=strftime("%s")} {print}'

然而,这又返回:

1
{null};2013-11-26;Text & Device;Location;/file/path/to/;1385848848;1;1385845647

大概是说,这意味着我在调用当前的epoch时间(1385848848是执行时的当前epoch),而不是要求strftime转换字符串;但我无法想象另一种方法来实现这一点。

gawk/strftime将现有时间戳转换为epoch的正确语法是什么?

编辑:这个问题似乎与如何在另一个命令中使用awk的输出松散相关?


1
2
3
4
5
$ cat file
{null};2013-11-26;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647

$ gawk 'BEGIN{FS=OFS=";"} {gsub(/-/,"",$2); $2=mktime($2" 0 0 0")}1' file
{null};1385445600;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647

以下是如何将日期从任何格式转换为从epoch开始的秒数,以当前格式为例,并带有注释,逐步显示转换过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ cat tst.awk
function cvttime(t,     a) {
    split(t,a,/[,: ]+/)
    # 2013 Tuesday, November 26 10:17 PM
    #  =>
    #    a[1] ="2013"
    #    a[2] ="Tuesday"
    #    a[3] ="November"
    #    a[4] ="26"
    #    a[5] ="10"
    #    a[6] ="17"
    #    a[7] ="PM"

    if ( (a[7] =="PM") && (a[5] < 12) ) {
        a[5] += 12
    }
    # => a[5] ="22"

    a[3] = substr(a[3],1,3)
    # => a[3] ="Nov"

    match("JanFebMarAprMayJunJulAugSepOctNovDec",a[3])
    a[3] = (RSTART+2)/3
    # => a[3] = 11

    return( mktime(a[1]""a[3]""a[4]""a[5]""a[6]" 0") )
}

BEGIN {
    mdt ="Tuesday, November 26 10:17 PM"
    secs = cvttime(2013""mdt)
    dt = strftime("%Y-%m-%d %H:%M:%S",secs)
    print mdt ORS"\t->" secs ORS"\t\t->" dt
}
$ awk -f tst.awk
Tuesday, November 26 10:17 PM
        -> 1385525820
                -> 2013-11-26 22:17:00

我相信你可以为目前的问题修改它。

另外,如果没有gawk,可以将cvttime()函数编写为(借用@sputnik的date命令字符串):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ cat tst2.awk
function cvttime(t,     cmd,secs) {
    cmd ="date -d "" t"" '+%s'"
    cmd | getline secs
    close(cmd)
    return secs
}

BEGIN {
    mdt ="Tuesday, November 26 10:17 PM"
    secs = cvttime(mdt)
    dt = strftime("%Y-%m-%d %H:%M:%S",secs)
    print mdt ORS"\t->" secs ORS"\t\t->" dt
}
$
$ awk -f tst2.awk
Tuesday, November 26 10:17 PM
        -> 1385525820
                -> 2013-11-26 22:17:00

我把srtftime()留在里面只是为了证明secs是正确的-根据您的需要用date替换。

对于非gawk版本,您只需按照date所理解的方式,了解如何将年份输入到输入的月份/日期/时间字符串中,这对您来说不应该很困难。


您可以使用以下代码段将日期转换为epoch:

1
2
$ date -d 'Tuesday, November 26 12:17 PM' +%s
1385464620

最后:

1
awk -F";" '{system("date -d ""$6"" '+%s'")}' file

感谢@keiron提供的片段。