csv - 使用 GAWK 将时间戳记转换为 CSV 文件中的 Epoch

标签 csv awk epoch gawk

希望使用 GAWK 将人类可读的时间戳转换为 CSV 文件中的纪元/Unix 时间,以准备加载到 MySQL 数据库中。

数据示例:

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

希望获取 11 月 26 日星期二中午 12:17 第 6 列,并转换为纪元时间进行存储。显示的所有时间均采用 EST 格式。我意识到 AWK 是执行此操作的工具,但似乎无法完全构建命令。目前有:

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

但是这会返回:

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

据推测,这意味着我正在调用当前纪元时间(1385848848 是执行时的当前纪元),而不是要求 strftime 转换字符串;但我无法想象还有其他方法可以做到这一点。

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

编辑:这个问题似乎与 How do I use output from awk in another command? 松散相关

最佳答案

$ 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

以下是如何将日期从任何格式转换为自纪元以来的秒数,以当前格式为例,并通过注释逐步显示转换过程:

$ 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 命令字符串):

$ 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() 留在那里只是为了表明秒数是正确的 - 根据您的需要替换为 date

对于非 gawk 版本,您只需要弄清楚如何以 date 能够理解的方式将年份放入输入月/日期/时间字符串中(如果这对您重要) - 应该别太难了。

关于csv - 使用 GAWK 将时间戳记转换为 CSV 文件中的 Epoch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20306217/

相关文章:

sql - 从纳秒时间戳按天分组

jodatime - 纪元时间可以倒退多远?

java - 某些日期无法在 Java 中正确转换为特定时区午夜的纪元时间戳

python - 通过多列中的非唯一值比较两个 csv 文件,输出到匹配的 csv 额外数据

unix tr 查找和替换

awk - 打印 `awk` 中的倒数第二列/字段

bash - 用一行将项目添加到逗号分隔列表

powershell - 如何比较两个具有不同标题行的 CSV 文件并从第一个文件中删除重复项?

csv - 无法使用golang读取csv文件中的json str

csv - 如何将 csv 文件读入 SWI prolog 中的列表列表,其中内部列表代表 CSV 的每一行?