Awk

使用 awk 獲取兩個日期的時差

  • September 15, 2018

我有一個大小為 7GB 的文件。現在有兩個日期時間,我想使用 awk 來獲取這兩個 DateTime 之間的時間差。

下面是我的文件的樣子:

A          B      C      D         E
18/06/28 09:19:07 295  141536 18-06-28 09:17:47
18/06/28 09:20:07 268  1160   18-06-28 09:18:58
18/06/28 09:21:07 317  1454   18-06-28 09:19:47
18/06/28 09:22:07 275  1491   18-06-28 09:20:59
18/06/28 09:23:07 320  1870   18-06-28 09:21:07
18/06/28 09:24:07 310  1869   18-06-28 09:22:30
18/06/28 09:25:07 150   693   18-06-28 09:23:28
18/06/28 09:26:07 414  2227   18-06-28 09:24:34 

我想要(AB)-(E)之間的區別。

我試過這個:

cat filename | awk -F " " '{print date -d ($1$2)-($5)}' 

輸出應該是兩個日期時間之間的時間差。就像第一行的差異將是 1 分 20 秒

使用 GNU awk:

gawk '
 function dt2epoch(date, time,      timestr) {
   timestr = "20" substr(date,1,2) " " substr(date,4,2) " " substr(date,7,2) \
              " " substr(time,1,2) " " substr(time,4,2) " " substr(time,7,2)
   return mktime(timestr)
 }
 function epoch2hms(t) {
   return strftime("%H:%M:%S", t, 1)
 }
 function abs(n) {return n<0 ? -1*n : n}
 NR == 1 {next}
 { print epoch2hms(abs(dt2epoch($5,$6) - dt2epoch($1,$2))) }
' file

輸出

00:01:20
00:01:09
00:01:20
00:01:08
00:02:00
00:01:37
00:01:39
00:01:33

對於 perl,我會使用DateTime生態系統:

perl -MDateTime::Format::Strptime -lane '
   BEGIN {$f = DateTime::Format::Strptime->new(pattern => "%y-%m-%d %H:%M:%S")}
   next if $. == 1;
   $F[0] =~ s{/}{-}g;
   $t1 = $f->parse_datetime("$F[0] $F[1]");
   $t2 = $f->parse_datetime("$F[4] $F[5]");
   $d = $t1->subtract_datetime($t2);
   printf "%02d:%02d:%02d\n", $d->hours, $d->minutes, $d->seconds;
' file

一個更快的 perl 版本,不需要任何非核心模組

perl -MTime::Piece -lane '
   next if $. == 1;
   $t1 = Time::Piece->strptime("$F[0] $F[1]", "%y/%m/%d %H:%M:%S");
   $t2 = Time::Piece->strptime("$F[4] $F[5]", "%y-%m-%d %H:%M:%S");
   $diff = gmtime(abs($t1->epoch - $t2->epoch));
   print $diff->hms;
' file

或者,備用輸出:

$ perl -MTime::Piece -lane '
   next if $. == 1;
   $t1 = Time::Piece->strptime("$F[0] $F[1]", "%y/%m/%d %H:%M:%S");
   $t2 = Time::Piece->strptime("$F[4] $F[5]", "%y-%m-%d %H:%M:%S");
   print abs($t1 - $t2)->pretty;
' file
1 minutes, 20 seconds
1 minutes, 9 seconds
1 minutes, 20 seconds
1 minutes, 8 seconds
2 minutes, 0 seconds
1 minutes, 37 seconds
1 minutes, 39 seconds
1 minutes, 33 seconds

引用自:https://unix.stackexchange.com/questions/452483