【问题标题】:How to convert Timestamp in UTC time using AWK如何使用 AWK 将时间戳转换为 UTC 时间
【发布时间】:2016-11-25 15:43:49
【问题描述】:

我尝试使用 awk 处理邮件日志文件,但在将时间戳转换为 UTC 格式时遇到问题。

输入文件如下所示:

# cat /tmp/TimeStamps1.tmp

2016-08-10T00:23:45.984558+02:00
2016-09-30T10:23:45.984558+02:00
2016-10-31T20:45:27.984558+01:00

预期的输出应该是:

cat /tmp/Target

2016-08-09 22:23:45
2016-09-30 08:23:45
2016-10-31 19:45:27

由于日期和时间之间的“T”似乎是个问题,我也尝试将其删除:

# cat /tmp/TimeStamps2.tmp

2016-08-10 00:23:45.984558+02:00
2016-09-30 10:23:45.984558+02:00
2016-10-31 20:45:27.984558+01:00

首先尝试使用 system()

awk ' {print $1" - "system("date -u +%Y-%m-%d -d" $0) } ' /tmp/TimeStamps2.tmp
date: extra operand `00:23:45.984558+02:00'
Try `date --help' for more information.
2016-08-10 - 1
date: extra operand `10:23:45.984558+02:00'
Try `date --help' for more information.
2016-09-30 - 1
date: extra operand `20:45:27.984558+01:00'
Try `date --help' for more information.
2016-10-31 - 1

第二次尝试使用 strftime()

/tmp$ awk -F',' ' {print $1" - "strftime( "%Y-%m-%d %H:%M:%S", $1)} ' /tmp/TimeStamps2.tmp
2016-08-10 00:23:45.984558+02:00 - 1970-01-01 01:33:36
2016-09-30 10:23:45.984558+02:00 - 1970-01-01 01:33:36
2016-10-31 20:45:27.984558+01:00 - 1970-01-01 01:33:36

【问题讨论】:

  • 日期工作查找:日期 -u +%Y-%m-%d' '%T -d"2016-08-10 00:23:45.984558+02:00" 2016-08 -09 22:23:45
  • 使用GAWK没问题,可以使用strftime和mktime。 mktime 期望的参数格式是“YYYY MM DD HH MM SS [DST]”形式的字符串。我将不得不尝试相应地重新格式化,对 [DST] 格式有什么建议吗?
  • 这提供了很好的结果:echo "2016-08-10 00:23:45.984558+02:00" | awk -F',' -v sep=\" ' { system("date -u +%Y-%m-%dT-%T -d" sep $1 sep ) } ' 2016-08-09T-22:23 :45 我必须在格式中有“T”,空格会引起问题。
  • awk ' { system("date -u +%Y-%m-%dT%T -d" \"" $1 \"" ); } ' TimeStamps2.tmp awk: { system("date -u +%Y-%m-%dT%T -d" \"" $1 \"" ); } awk: ^ 反斜杠不是最后一个字符

标签: ubuntu awk utc strftime


【解决方案1】:

现在听起来这就是你真正想要做的事情:

$ cat file
2016-08-10T00:23:45.984558+02:00 here is the first line
2016-09-30T10:23:45.984558+02:00 and here's the second
2016-10-31T20:45:27.984558+01:00 oh look, a third!

$ awk '{
    ts=$1; sub(/T/," ",ts); sub(/[^ ]+ /,"")
    cmd="date -u +\"%Y-%m-%d %T\" -d \"" ts "\""
    if ((cmd | getline line) > 0) {
        print line, $0
    }
    close(cmd)
}' file
2016-08-09 22:23:45 here is the first line
2016-09-30 08:23:45 and here's the second
2016-10-31 19:45:27 oh look, a third!

【讨论】:

    【解决方案2】:

    这是第一个答案,感谢 Ed Morton!

    awk ' { A=$1" "$2;system("date -u +%Y-%m-%d\" \"%T -d \""A"\""  ); } ' TimeStamps2.tmp
    2016-08-09 22:23:45
    2016-09-30 08:23:45
    2016-10-31 19:45:27
    

    【讨论】:

    • 改用"date -u +\"%Y-%m-%d %T\" -d \""A"\""。引用整个字符串而不是其中的单个空格更合理/常见/可读:"foo bar" 而不是 foo" "bar
    • 确实,非常感谢。我注意到 system() 命令的结果在 awk 脚本中不可用,如果我尝试转换 mail.log 文件,则只有时间戳可用作输出:(
    • 对,system(cmd) 不是你这样做的,cmd | getline 是。这让我们回到了您获得的第一个 cmets,它提供了简洁、可测试的样本输入和预期输出,因此我们可以帮助您做您真正想做的事情,而不仅仅是帮助您实现您认为的需要实施。
    猜你喜欢
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多