【问题标题】:using awk to modify multiple columns使用 awk 修改多列
【发布时间】:2018-08-25 20:48:29
【问题描述】:

我有一个包含两列的 csv 文件:ISO8601 中的日期字符串和 linux 时间戳。如何使用awk 获取以下格式的输出: col-1: original ISO; col-2:将时间戳(2)转换为ISO8601; col-3:两次之间的差异(例如,以毫秒为单位)

例子:

输入

  2018-01-09T16:55:22.545+0000,1515508979185

输出

  2018-01-09T16:55:22.545+0000,2018-01-09T14:42:59.185+0000,36743360

【问题讨论】:

  • 不清楚,请在您的帖子中发布更明确的问题要求并提供更合适的示例。
  • 我不确定计算两个日期之间的差异并将它们标准化为相同的 ISO 8601 格式有什么不清楚的地方。您能否更具体地说明不清楚的地方?

标签: linux awk command-line


【解决方案1】:

Gawk 具有在不同格式之间转换日期和时间所需的所有功能。这是一个 Gawk 扩展。

考虑以下命令

awk -F, '{ patsplit($1,a,"[0-9]*");
      time1 = mktime(sprintf("%d %d %d %d %d %d",
                   a[1], a[2] ,a[3], a[4], a[5], a[6]))*1000 + a[7];
      time2 = mktime(strftime("%Y %m %d %H %M %S",$2/1000,a[8]))*1000 +$2 %1000;  
      isodate2 = strftime("%Y-%m-%dT%H:%M:%S",$2/1000,a[8]);
      printf "%s;%s.%03d;%s\n",
             $1,
             isodate2,$2 % 1000,
             time1 - time2}' csvfile

它会产生

2018-01-09T16:55:22.545+0000;2018-01-09T14:42:59.185;7943360

说明

我们使用, 作为字段分隔符,因为输入是 CSV 文件。 首先我们解析第一列参数,它是一个 ISO 8601 日期。我们使用patsplit() 将ISO 8601 字符串中的所有数字提取到数组a 中,这样

  a[1] = YYYY, a[2] = mm, a[3] = dd, 
  a[4] = HH, a[5] = MM, a[6] = SS, a[7] = uuu

我们使用数组a 将第一列日期转换为时间戳并计算以微秒为单位的差异并将结果存储在time1 变量中。

这里处理时区需要计算第一个时间戳的时区中第二个时间的等值。

然后我们从第一列开始打印输出行;使用strftime 将时间戳从第 2 列转换为 ISO8601 日期并分别打印微秒。

time1 和 time2 的区别与原帖不同。

【讨论】:

  • 你应该提到那是时间函数的 gawk-only。
【解决方案2】:

awk解决方案:

awk 'BEGIN{ FS=OFS="," }
     { 
         cmd1 = "date -d"$1" +%s"; 
         cmd2 = "date -d@"int($2/1000)" +%FT%T.%3N%z";
         cmd1 | getline d1; close(cmd1);
         cmd2 | getline d2; close(cmd2);
         print $1, d2, d1*1000 - $2 
     }' file

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 2012-11-23
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多