格式化和计算日期之间的时差(awk / sed)

时间:2015-11-19 11:34:37

标签: bash date awk sed timestamp

我正在尝试计算格式如下的日期之间的时差:

  

dd / mm / YY; hh:mm:ss; dd / mm / YY; hh:mm:ss (第一对dd / mm / YY; hh:mm:ss指出开始日期和第二对夫妇是   结束日期)

我希望输出如下:

  

dd / mm / YY; hh:mm:ss; dd / mm / YY; hh:mm:ss; hh:mm:ss ,其中添加的hh:mm:ss是两个日期之间的时差。

以下是一个例子:

end

我用 gsub,mktime和awk 尝试了很多东西,以便格式化日期,但没有什么是足够有效的(格式和分割操作太多)。

这是我的尝试:

INPUT:
12/11/15;20:04:09;13/11/15;08:46:26
13/11/15;20:05:34;14/11/15;08:42:04
14/11/15;20:02:47;16/11/15;08:44:43

OUTPUT:
12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56

你有什么建议? 谢谢:))

3 个答案:

答案 0 :(得分:1)

您可以尝试此操作并保存一些gsubsubstr来电:

awk -F'[:;/]' '{d1=mktime("20"$3" "$2" "$1" "$4" "$5" "$6);
                d2=mktime("20"$9" "$8" "$7" "$10" "$11" "$12); 
                delta = d2-d1
                sec = delta%60
                min = (delta - sec)%3600/60
                hrs = int(delta/3600)
                print $0";"(hrs < 10 ? "0"hrs : hrs)\
                        ":"(min < 10 ? "0"min : min)\
                        ":"(sec < 10 ? "0"sec : sec);}' time.txt

由于我们不能使用strftime(坦克到Ed Morton),我们必须处理小时&gt; 23或小时/分钟/秒< 10手动。 上面的代码输出:

14/11/15;20:02:47;16/11/15;08:44:43;36:41:56
14/11/15;20:02:47;14/11/15;20:02:48;00:00:01

输入

14/11/15;20:02:47;16/11/15;08:44:43
14/11/15;20:02:47;14/11/15;20:02:48

答案 1 :(得分:1)

如果没有mktime(),你不能强有力地完成这项工作,因为时差计算需要考虑闰日,闰秒等。我认为你不能比这更有效地做到这一点:

$ cat tst.awk
BEGIN { FS="[/;:]" }
{
    d1 = mktime("20"$3" "$2" "$1" "$4" "$5" "$6)
    d2 = mktime("20"$9" "$8" "$7" "$10" "$11" "$12)
    delta = d2 - d1
    hrs = int(delta/3600)
    min = int((delta - hrs*3600)/60)
    sec = delta - (hrs*3600 + min*60)
    printf "%s;%02d:%02d:%02d\n", $0, hrs, min, sec
}

$ awk -f tst.awk file
12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56

注意 - 您不能使用strftime()[单独]来计算小时,分钟和秒,因为当您的delta值超过1天时,strftime()将返回与时间相关的小时,分​​钟和秒在该delta的最后一天,而不是与整个delta相关联的hrs,min和sec的总数。

答案 2 :(得分:0)

你所要求的将是相当棘手的传统awk。

当然,gawk(GNU awk)支持mktime,但其他awk实现则不支持。但是你可以直接在bash中执行此操作,依靠date命令进行转换。此解决方案使用BSD日期(因此它可以在FreeBSD,NetBSD,OpenBSD,OSX等中使用)。

while IFS=\; read date1 time1 date2 time2; do
  stamp1=$(date -j -f '%d/%m/%y %T' "$date1 $time1" '+%s')
  stamp2=$(date -j -f '%d/%m/%y %T' "$date2 $time2" '+%s')
  d=$((stamp2-stamp1))
  printf '%s;%s;%s;%s;%02d:%02d:%02d\n' "$date1" "$time1" "$date2" "$time2" $(( (d/3600)%60)) $(( (d/60)%60 )) $((d%60))
done < dates.txt

结果:

12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56

当然,如果您使用的是非BSD操作系统,则可能必须安装bsddate(如果可用)才能获得此功能,或者使用您手头的工具找出如何获得相同的功能。< / p>