【问题标题】:How to retain millisecond information while using mktime in awk?在awk中使用mktime时如何保留毫秒信息?
【发布时间】:2013-02-21 05:37:05
【问题描述】:

我有一个格式为 2012-12-20T01:16:02.05 的日期字符串,我想转换为格式 2011-12-20-01.16.02.050000

目前我的做法如下

format = "%F-%H.%M.%S.%N"
split(stringinput,input,"T"); 
split(input[1],date,"-")
split(input[2],time,":")

 return strftime(format,mktime(date[1] " " date[2] " " date[3] " " time[1] " " time[2] " " time[3] " " time[4]));

但我正在丢失微秒信息或毫秒信息。我怎么能得到那个。它正在返回 2011-12-20-01.16.02.%N

还有使字符串解析更通用的任何建议。目前只支持一种格式。

谢谢。

【问题讨论】:

    标签: date awk strftime mktime


    【解决方案1】:

    您需要单独处理毫秒数据。此外,使用gensub() 格式化您的字符串信息。运行如下:

    awk -f script.awk
    

    script.awk的内容:

    BEGIN {
    
        string = "2012-12-20T01:16:02.05"
    
        groups = "^(....)-(..)-(..).(..):(..):(..).*"
        format = "\\1 \\2 \\3 \\4 \\5 \\6"
    
        datespec = gensub(groups, format, "", string)
        timestamp = mktime(datespec)
    
    
        newstring = strftime("%F-%H.%M.%S", timestamp)
    
        sub(/.*\./,"",string)
    
        printf "%s.%s0000\n", newstring, string
    }
    

    结果:

    2012-12-20-01.16.02.050000
    

    编辑:

    BEGIN {
    
        string = "2011-01-10T14:45:13.815-05:00"
    
        groups = "^(....)-(..)-(..).(..):(..):(..).*"
        format = "\\1 \\2 \\3 \\4 \\5 \\6"
    
        datespec = gensub(groups, format, "", string)
        timestamp = mktime(datespec)
    
    
        sub(/.*\./,"",string)
    
        offset = substr(string,4)
    
        split(offset,array,":")
    
        seconds = (array[1] * 60 * 60) + (array[2] * 60)
    
        newstring = strftime("%F-%H.%M.%S", timestamp - seconds, 1)
    
        printf "%s.%s00\n", newstring, substr(string,0,3)
    }
    

    结果:

    2011-01-10-09.45.13.81500
    

    【讨论】:

    • 嗨史蒂夫,谢谢它的工作。但是您能否建议我如何使其通用以处理任何格式的输入。
    • @PriyaRanjan:any 格式?那会很困难。您可能可以使用循环测试几个不同的正则表达式。如果mktime() 不返回-1,则break 循环。如果您列出几种不同的日期时间格式,也许我可以告诉您具体的方式。
    • 我已经浏览了列表,似乎我拥有的格式是上述格式,并添加了时区信息。
    • @PriyaRanjan:您能否将这些数据粘贴到您的问题中?预期的输出也会很有帮助。
    • 我浏览了列表,似乎我拥有的格式是上述格式,并添加了时区信息,如 2011-01-10T14:45:13.815-05:00 。这里的时区是 UTC-05:00 。你能建议我如何处理这个问题吗?我通读了 mktime 规范,它似乎不处理时区。
    【解决方案2】:

    为什么要使用 mktime()?您描述的更改只是文本更改:

    $ echo "2012-12-20T01:16:02.05" | awk '{sub(/T/,"-"); gsub(/:/,"."); print $0 "0000"}'
    2012-12-20-01.16.02.050000
    

    我假设您在输出中将 2012 更改为 2011 时只是一个错字。

    【讨论】:

      【解决方案3】:

      因为我希望我的 GNU 日期精度与 awk 匹配,所以我必须按以下方式进行:

      x='2019-05-30 14:09:20.074'
      echo $x | awk '{split($1,a,"-");;split($2,b,".");split(b[1],c,":");s=a[1]" "a[2]" "a[3]" "c[1]" "c[2]" "c[3];tt=mktime(s);print tt b[2] "000000"}'
      1559196560074000000
      
      date --date=$x +'%s%N'
      1559196560074000000
      

      现在,我能够使这两者达成一致,我现在可以在 awk 中进行比较逻辑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多