我有以下模式的日志,我需要一个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
平均值将是所有差值的总和除以总行数
答案 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
答案 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循环中,您可以在读取文件时添加所有字段或进行比较。在你的情况下,你会减去时间戳并以秒为单位取差异并对它们做一些事情(例如转换为分钟/小时等)。