awk 在报告中使用以毫秒为单位的时间差

awk 在报告中使用以毫秒为单位的时间差

我需要解析如下所示的日志文件。

09/03/2020 00:05:03.364 Aggregated 1000 NMEs at a rate of 0 NMEs/sec
09/03/2020 00:05:03.366 Scheme S20_SessionClassAggregation tree contained 1000 nmes, 500 flushed, 0 remain.
09/03/2020 00:05:03.582 Flushed 1000 NMEs at a rate of 0 NMEs/sec
09/03/2020 00:20:03.598 Aggregated 2000 NMEs at a rate of 0 NMEs/sec
09/03/2020 00:20:03.602 Scheme S20_SessionClassAggregation tree contained 2000 nmes, 1000 flushed, 0 remain.
09/03/2020 00:20:03.860 Flushed 2000 NMEs at a rate of 0 NMEs/sec

我需要计算报告末尾从第 3 行 ( 009/03/2020 00:05:03.582) 到第 1 行 ( 09/03/2020 00:05:03.364) 以及从第 6 行 ( 09/03/2020 00:20:03.860) 到第 4 行 ( ) 的时间戳差异,即“聚合”和关联的“刷新”之间的时间差09/03/2020 00:20:03.598日志条目。

我已经尝试过以下awk程序,但它没有按预期工作,并且我不确定如何使用awk.

awk '$3 == "Aggregated" {Agg_date=$1" "$2;Aggregated=$4}
     $3=="Flushed" {Flush_date=$1" "$2;Flushed=$4} 
     $4=="S20_SessionClassAggregation" {S20_Flushed=$9}
    {printf Aggregated" "S20_Flushed" "Flushed " "Flush_date" "Agg_date "\n"}' test.txt 

预期成绩:

Aggregated  S20_Flushed   Flushed      Flush_date             Agg_date                  Tme difference between
                                                                                        Flushdate - Agg_date

1000        500            1000       09/03/2020 00:05:03.582 09/03/2020 00:05:03.364  0 min 0 sec 218 ms

2000        1000           2000       09/03/2020 00:20:03.860 09/03/2020 00:20:03.598  0 min 0 sec 262 ms
.
.
.

答案1

以下是如何使用 GNU awk for 进行您询问的计算mktime()

$ cat tst.awk
$3 == "Aggregated" {
    aggDt = $1 " " $2
}

$3 == "Flushed" {
    fluDt = $1 " " $2
    aggMs = dt2ms(aggDt)
    fluMs = dt2ms(fluDt)
    difMs = fluMs - aggMs
    print fluDt, aggDt, difMs
}

function dt2ms(dt,      t, ms) {
    split(dt,t,"[/ :.]")
    ms = mktime(t[3]" "t[1]" "t[2]" "t[4]" "t[5]" "t[6]) * 1000 + t[7]
    return ms
}

$ awk -f tst.awk file
09/03/2020 00:05:03.582 09/03/2020 00:05:03.364 218
09/03/2020 00:20:03.860 09/03/2020 00:20:03.598 262

我确信您可以弄清楚如何将 ms 转换为您想要的分钟/秒/毫秒格式,并以您需要的任何格式添加您需要的任何其他信息,就像在现有脚本中一样。

答案2

只要做算术就可以了。拆分每行上的时间戳,并计算自午夜以来的秒数(包括毫秒)。

function getSecs (Ts, Local, V) {

    split (Ts, V, /:/);
    return (3600 * V[1] + 60 * V[2] + V[3]);
}

为每一行调用它,例如

Secs[NR] = getSecs( $2);

这将为您提供一个按行号索引的数组。您需要的唯一修复是,如果时间戳向后跳转,则您运行了一个午夜,并且必须为该比较添加 86400。如果您的日志可以跳过一整天,那么这将不起作用,但这在这里看起来不是问题。

GNU/awk只需要一点点工作,就可以很好地完成约会工作。如果您将数据重新排列成类似字符串YYYY MM DD HH MM SS [DST]并将其传递给mktime(),您将获得自纪元以来的秒数。您可以调整任何字段(例如将月份值添加 19,将天数减去 73),它会在内部进行调整。您可以使用 输出任何您喜欢的格式strftime()。 (您需要单独添加毫秒。)

相关内容