使用awk修改多个列

时间:2018-03-16 17:39:21

标签: linux awk command-line

我有一个包含两列的csv文件:ISO8601中的日期字符串和linux时间戳。如何使用awk以下列格式获取输出:col-1:原始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

2 个答案:

答案 0 :(得分: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变量中。

此处理时区需要计算第一个时间戳的时区中第二次的等效值。

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

time1和time2之间的差异与原始帖子不同。

答案 1 :(得分:1)

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