比较两个连续日志条目之间的时间

时间:2014-09-01 15:43:11

标签: bash date

我有一个包含以下内容的日志文件:

01.09.14 14:53:34 UTC 10.10.10.1 RTT was 105ms
01.09.14 14:55:08 UTC 10.10.2.45 RTT was 227ms
01.09.14 14:58:08 UTC 10.10.44.3 RTT was 212ms
01.09.14 14:59:21 UTC 10.10.10.1 RTT was 218ms
01.09.14 15:02:38 UTC 10.10.3.9 RTT was 185ms
01.09.14 15:10:38 UTC 10.10.10.1 RTT was 171ms
01.09.14 15:38:38 UTC 10.10.2.45 RTT was 143ms

我想将每一行与下一行进行比较,如果它们相隔<60秒,则创建一个新日志文件的条目。我的想法是将时间戳转换为适合日期工具的输入格式,然后将时间转换为纪元时间,最后从另一个值中减去一个值。是否有更好或更聪明的算法来实现相同的目标?

2 个答案:

答案 0 :(得分:3)

我会使用GNU awk,它具有内置的时间函数

awk '
  {
    split($1, d, /[.]/)
    split($2, t, /:/)
    this_t = mktime("20"d[3]" "d[2]" "d[1]" "t[1]" "t[2]" "t[3])
  }
  NR == 1 { print; prev = this_t; next}
  {
    print "elapsed: ", this_t - prev
    print
    prev = this_t
  }
' file
01.09.14 14:53:34 UTC 10.10.10.1 RTT was 105ms
elapsed:  94
01.09.14 14:55:08 UTC 10.10.2.45 RTT was 227ms
elapsed:  180
01.09.14 14:58:08 UTC 10.10.44.3 RTT was 212ms
elapsed:  73
01.09.14 14:59:21 UTC 10.10.10.1 RTT was 218ms
elapsed:  197
01.09.14 15:02:38 UTC 10.10.3.9 RTT was 185ms
elapsed:  480
01.09.14 15:10:38 UTC 10.10.10.1 RTT was 171ms
elapsed:  1680
01.09.14 15:38:38 UTC 10.10.2.45 RTT was 143ms

答案 1 :(得分:2)

让我们一起玩日期:

while read -r dat hour rest
do
    secs=$(date -d"${dat//.//} $hour" "+%s")
    [ $((secs - prev)) -ge 60 ] && echo "$dat $hour $rest"
    prev=$secs
done < file > output

解释

  • while read -r dat hour rest读取三个块中的每一行:第一行包含日期,第二行包含小时,最后一行包含其余内容。
  • ${dat//.//}会在日期字段中将点转换为斜杠(. - &gt; /),以便date正确解释它。
  • secs=$(date -d"${dat//.//} $hour" "+%s")将日期转换为自1970年1月1日以来的秒数。这样我们就可以相互比较。
  • [ $((secs - prev)) -ge 60 ] && echo "$dat $hour $rest"将当前秒数与之前的秒数进行比较。如果差异为g reater或e qual而不是60,则输出整行。
  • prev=$secs存储下一循环的当前秒数。
  • while read; do ... done < file > outputfile读取并输出到output文件。

调试:

while read -r dat hour rest
do
    secs=$(date -d"${dat//.//} $hour" "+%s")
    echo "the date in seconds is $secs"
    [ $((secs - prev)) -ge 60 ] && echo "OUTPUT: $dat $hour $rest" > output
    prev=$secs
done < file

返回:

$ while read -r dat hour rest; do secs=$(date -d"${dat//.//} $hour" "+%s"); echo "the date in seconds is $secs"; [ $((secs - prev)) -ge 60 ] && echo "OUTPUT: $dat $hour $rest";     prev=$secs; done < file
the date in seconds is 1389275614
the date in seconds is 1389275708
OUTPUT: 01.09.14 14:55:08 UTC 10.10.2.45 RTT was 227ms
the date in seconds is 1389275888
OUTPUT: 01.09.14 14:58:08 UTC 10.10.44.3 RTT was 212ms
the date in seconds is 1389275961
OUTPUT: 01.09.14 14:59:21 UTC 10.10.10.1 RTT was 218ms
the date in seconds is 1389276158
OUTPUT: 01.09.14 15:02:38 UTC 10.10.3.9 RTT was 185ms
the date in seconds is 1389276638
OUTPUT: 01.09.14 15:10:38 UTC 10.10.10.1 RTT was 171ms
the date in seconds is 1389278318
OUTPUT: 01.09.14 15:38:38 UTC 10.10.2.45 RTT was 143ms