如何从日志文件中查找特定模式匹配字符串的平均时间

时间:2018-06-01 11:03:28

标签: bash shell awk grep

我有以下模式的日志,我需要一个shell脚本,它可以grep模式Forged new block id并计算匹配模式Forged new block id的时间戳列的平均时间。

[inf] 2018-06-01 07:32:20 | Forged new block id: 17422268043238265953 height: 6 round: 1 slot: 6372914 reward: 0
[inf] 2018-06-01 07:32:30 | Forged new block id: 12637471709620273874 height: 7 round: 1 slot: 6372915 reward: 0
[inf] 2018-06-01 07:33:31 | Forged new block id: 9854455515089974346 height: 13 round: 1 slot: 6372921 reward: 0
[inf] 2018-06-01 07:35:34 | Forged new block id: 9528299565814967922 height: 25 round: 1 slot: 6372933 reward: 0
[inf] 2018-06-01 07:37:44 | Forged new block id: 4030154355419311374 height: 38 round: 1 slot: 6372946 reward: 0
[inf] 2018-06-01 07:38:34 | Forged new block id: 15961811681976216620 height: 43 round: 1 slot: 6372951 reward: 0
[inf] 2018-06-01 07:39:03 | Forged new block id: 18327854550540255433 height: 46 round: 1 slot: 6372954 reward: 0
[inf] 2018-06-01 07:43:05 | Forged new block id: 6436183970195006511 height: 70 round: 1 slot: 6372978 reward: 0
[inf] 2018-06-01 07:44:34 | Forged new block id: 2865139280099855691 height: 79 round: 1 slot: 6372987 reward: 0
[inf] 2018-06-01 07:45:45 | Forged new block id: 5462796790425133759 height: 86 round: 1 slot: 6372994 reward: 0

预期结果是当前行与其上一行之间的时差让我们说2018-06-01 07:32:20这是第一行,这是第二行2018-06-01 07:32:30所以时差为10 seconds平均值将是所有差值的总和除以总行数

3 个答案:

答案 0 :(得分:3)

您可以使用此GNU awk脚本:

$ awk '/Forged new block id/{timestr=$2" "$3;gsub(/[-:]/," ",timestr);t1=mktime(timestr);if(t2) {diff=t1-t2;print diff} t2=t1; total+=diff} END{print "average=" total/NR}' file
10
61
123
130
50
29
242
89
71
average=80.5

该脚本将第2和第3个字段转换为mktime awk命令可以理解的日期字符串。

时间戳差异是根据最后一行计算的。

END以秒为单位打印平均值。

答案 1 :(得分:1)

您可以使用此awk来计算平均时间:

awk 'function getSec(s) {
   cmd = "date +%s -d \"" s "\""
   cmd | getline d
   close( cmd )
   return d
}
/Forged new block id/ {
   ++n
   ts = $2 OFS $3
   if (n == 1)
      start = ts
}
END {
   print (getSec(ts) - getSec(start)) / n
}' file

80.5

Online Working Demo

答案 2 :(得分:0)

只需将时间转换为时间戳并对其进行数学运算。

例如。把人变成纪元(例如," Apr 28 07:50:01"到1524916201),然后减去它们添加它们等等。

在这个例子中,我有一个来自" human"可读的,如果你要时间戳和回来。当我写一个脚本来告诉我crons何时开始以及它们何时实际完成时,我发现这很有用。

示例:从人类转换为纪元函数

#!/bin/bash
# -- Converts from human to epoch or epoch to human, 
#    specifically this format: "Apr 28 07:50:01" human.
#    typeset now=$(date +"%s")
#    typeset now_human_date=$(convert_cron_time "human" "$now")

function convert_cron_time() {
    case "${1,,}" in
        epoch)
            # human to epoch (eg. "Apr 28 07:50:01" to 1524916201)
            echo $(date -d "${2}" +"%s")
            ;;
        human)
            # epoch to human (eg. 1524916201 to "Apr 28 07:50:01")
            echo $(date -d "@${2}" +"%b %d %H:%M:%S")
            ;;
    esac
}


now=$(date +"%s")
time_range=604800   #one week in seconds
start=$now
finish=$((($now+$time_range)))


start_human=$(convert_cron_time "human" "$start")
finish_human=$(convert_cron_time "human" "$finish")

start_epoch=$(convert_cron_time "epoch" "$start_human")
finish_epoch=$(convert_cron_time "epoch" "$finish_human")

echo "$start_human / $start_epoch"
echo "$finish_human / $finish_epoch"

another=$(convert_cron_time "epoch" "2018-06-01 07:32:20")
another_human=$(convert_cron_time "human" "$another")
echo "another ex: $another / $another_human"

输出:

Jun 01 08:47:34 / 1527857254
Jun 08 08:47:34 / 1528462054
another ex: 1527852740 / Jun 01 07:32:20

因此,在for循环中,您可以在读取文件时添加所有字段或进行比较。在你的情况下,你会减去时间戳并以秒为单位取差异并对它们做一些事情(例如转换为分钟/小时等)。