将时间戳转换为就地文件中的纪元

Dru*_*ght 3 vim bash awk sed gawk

我有一个制表符分隔文件,在第三个字段中有时间戳,我需要在bash中更改为epoch.

样本输入:

xyz@gmail.com   SALE    2017-04-26 12:47:27     30.0    1       201704
xyz@gmail.com   SALE    2017-04-26 12:46:15     20.0    2       201704
xyz@gmail.com   PAYBACK 2017-04-18 08:02:31     95.0    3       201704
xyz@gmail.com   SEND    2017-04-18 08:00:37     4800.0  4       201704
xyz@gmail.com   SEND    2017-04-17 14:59:34     4900.0  5       201704
Run Code Online (Sandbox Code Playgroud)

我尝试过awk 'BEGIN {IFS="\t"} {$3=system("date -d \""$3"\" '+%s'");print}' file,它给出了最接近的结果,但它在一行中显示了纪元,然后在换行符中再次显示记录,时间戳值为零.我要求所有人都在一个记录中替换第三个字段.

Ed *_*ton 5

使用GNU awk:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    $3 = mktime(gensub(/[-:]/," ","g",$3))
    print
}

$ awk -f tst.awk file
xyz@gmail.com   SALE    1493228847      30.0    1       201704
xyz@gmail.com   SALE    1493228775      20.0    2       201704
xyz@gmail.com   PAYBACK 1492520551      95.0    3       201704
xyz@gmail.com   SEND    1492520437      4800.0  4       201704
xyz@gmail.com   SEND    1492459174      4900.0  5       201704
Run Code Online (Sandbox Code Playgroud)

与其他awks:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    cmd = "date -d \"" $3 "\" \047+%s\047"
    if ( (cmd | getline line) > 0 ) {
        $3 = line
    }
    close(cmd)
    print
}

$ awk -f tst.awk file
xyz@gmail.com   SALE    1493228847      30.0    1       201704
xyz@gmail.com   SALE    1493228775      20.0    2       201704
xyz@gmail.com   PAYBACK 1492520551      95.0    3       201704
xyz@gmail.com   SEND    1492520437      4800.0  4       201704
xyz@gmail.com   SEND    1492459174      4900.0  5       201704
Run Code Online (Sandbox Code Playgroud)

你的脚本 - 没有内置的awk变量命名IFS,system返回最后一个命令运行的退出状态,而不是它的标准输出,你不能''从shell调用的任何定界脚本中包含s .

想要"就地"执行此操作,没有UNIX编辑器真的可以就地编辑,但是在GNU awk中你可以使用它-i inplace来避免自己指定tmp文件名.但是,使用任何UNIX命令,您都可以这样做cmd file > tmp && mv tmp file.

请注意,这是极少数适当的用途之一getline- 请参阅http://awk.freeshell.org/AllAboutGetline了解其他有效用途,最重要的是,除非绝对必要,否则请注意不要使用它.