在日志文件中计算时间

时间:2014-09-04 06:33:09

标签: linux bash unix awk sed

我的日志文件如下所示:

log.txt的

Unavailable 06.08.2014 23:59:36 - 07.08.2014 00:00:36
Unavailable 15.08.2014 04:53:32 - 15.08.2014 04:53:32
Available   15.08.2014 04:54:32 - 15.08.2014 05:17:32
Unavailable 15.08.2014 05:18:32 - 15.08.2014 05:18:32
Unavailable 15.08.2014 08:22:00 - 15.08.2014 08:22:00
Available   15.08.2014 08:23:00 - 17.08.2014 01:44:27
Unavailable 17.08.2014 01:45:27 - 17.08.2014 01:52:33
Available   17.08.2014 01:53:33 - 02.09.2014 11:07:21

我需要以秒为单位计算不可用时间。我不是任何sed / awk大师所以我对这个问题的解决很简单:

cat log.txt | grep "Unav" | sed -r 's/\<Unavailable\>//g;s/:/ /g;s/\./ /g' | 
awk -F- '{d2=mktime($2);d1=mktime($1);print d2-d1;}' | awk '{s+=$1} END {print s}'

我很惊讶地看到当日期过了一天(午夜时分)时,计算出错了。计算第一行的结果显示EPOCH中的差异 31449660 秒,因此它将是 Thu Dec 31 01:01:00 CET 1970 。但计算结果应为60秒。有人可以解释一下为什么这个结果是从系统返回的吗?

2 个答案:

答案 0 :(得分:3)

如果您要使用sed,则不需要grepawk。此外,从样本数据中显示的差异应为60秒。

来自man页面:

  

mktime(datespec)将datespec转换为与时间相同的时间戳   由systime()返回。它类似于同名的功能   在ISO C中。参数,datespec,是一个形式为“YYYY MM DD”的字符串   HH MM SS [DST]“。

尝试以下命令:

awk '
$1 == "Unavailable" { 
    split ($2, d1, /[.]/);
    split ($3, t1, /:/);
    split ($5, d2, /[.]/);
    split ($6, t2, /:/);
    end   = mktime (d2[3]" "d2[2]" "d2[1]" "t2[1]" "t2[2]" "t2[3])
    start = mktime (d1[3]" "d1[2]" "d1[1]" "t1[1]" "t1[2]" "t1[3])
    print end - start
}' log.txt
60
0
0
0
426

这将以秒为单位打印差异。如果您希望以其他格式打印输出,可以使用GNU awk库中的strftime函数。

答案 1 :(得分:0)

在我的系统上,man awkmktime(datespec)需要格式YYYY MM DD HH MM SS。但是你正在通过06 08 2014 23 59 36,它有年和日交换。你需要重新安排这些领域。