linux - 在日志文件中计算时间

标签 linux bash unix awk sed

我的日志文件格式如下:

日志.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 秒。谁能解释一下为什么系统会返回这个结果?

最佳答案

如果您要使用 awk,则不需要所有的 sedgrep。此外,如样本数据所示,差异应为 60 秒。

来自 man 页面:

mktime(datespec) Turn datespec into a timestamp in the same form as is returned by systime(). It is similar to the function of the same name in ISO C. The argument, datespec, is a string of the form "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

这将以秒为单位打印差异。如果你想以另一种格式打印输出,你可以使用 strftime来自 GNU awk 库的函数。

关于linux - 在日志文件中计算时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25658664/

相关文章:

linux - 从 perl 执行挂载系统调用

mysql - 如何使用 cygwin 来同步文件?

arrays - 如何在单行上打印 bash 数组的输出

bash - 意外的运算符(operator)错误

java - JSch lls 命令不反射(reflect) lcd 命令的目录更改

linux - 在 *nix 中,我们可以只为一个命令提供脚本吗?

linux - 如何实时监控每个文件的 Linux 文件访问

linux - 使用Go生成适用于`/etc/shadow`的哈希密码字符串

linux - 如何避免 iconv 错误来停止我的程序

Unix:如何读取多行?