按4小时间隔统计日志文件各级别消息数量的Bash脚本需求
按4小时间隔统计日志级别数量的Awk脚本
没问题,我来帮你搞定按4小时间隔统计日志级别的需求!你的原始方法用了多个管道,其实我们可以用单awk脚本一次性完成,既高效又清晰,还能直接输出规整的统计表格。
核心脚本(单天日志场景)
如果你的日志是单天的,或者你希望合并不同日期的同一4小时区间统计,用这个脚本:
awk ' BEGIN { # 预定义所有4小时时间区间 intervals["00-03"] = 0 intervals["04-07"] = 0 intervals["08-11"] = 0 intervals["12-15"] = 0 intervals["16-19"] = 0 intervals["20-23"] = 0 # 初始化每个区间的各级别计数为0 for (intv in intervals) { count[intv]["INFO"] = 0 count[intv]["WARNING"] = 0 count[intv]["ERROR"] = 0 } } { # 从日志时间字段中提取小时数 split($2, time_parts, ":") hour = time_parts[1] # 判断当前日志属于哪个4小时区间 if (hour >= 0 && hour < 4) { current_intv = "00-03" } else if (hour >= 4 && hour < 8) { current_intv = "04-07" } else if (hour >= 8 && hour < 12) { current_intv = "08-11" } else if (hour >= 12 && hour < 16) { current_intv = "12-15" } else if (hour >= 16 && hour < 20) { current_intv = "16-19" } else { current_intv = "20-23" } # 对应级别的计数+1 if ($4 == "INFO") { count[current_intv]["INFO"]++ } else if ($4 == "WARNING") { count[current_intv]["WARNING"]++ } else if ($4 == "ERROR") { count[current_intv]["ERROR"]++ } } END { # 输出规整的统计表头 printf "%-12s %6s %8s %6s\n", "时间区间", "INFO", "WARNING", "ERROR" printf "%-12s %6s %8s %6s\n", "----------", "----", "-------", "-----" # 按时间顺序输出统计结果(避免awk数组遍历的随机顺序) ordered_intvs[1] = "00-03" ordered_intvs[2] = "04-07" ordered_intvs[3] = "08-11" ordered_intvs[4] = "12-15" ordered_intvs[5] = "16-19" ordered_intvs[6] = "20-23" for (i=1; i<=6; i++) { intv = ordered_intvs[i] printf "%-12s %6d %8d %6d\n", intv, count[intv]["INFO"], count[intv]["WARNING"], count[intv]["ERROR"] } } ' your_log_file.log
脚本解释
- BEGIN块:提前定义所有4小时区间,并初始化每个区间的三个日志级别计数为0,避免统计时出现未定义的情况。
- 主处理块:
- 拆分日志的时间字段(
$2),提取小时数; - 根据小时数判断当前日志所属的4小时区间;
- 匹配日志级别(
$4),对应区间的计数加1。
- 拆分日志的时间字段(
- END块:格式化输出统计结果,并且手动指定区间的输出顺序,保证结果按时间从早到晚排列。
扩展:跨日志按「日期+4小时区间」统计
如果你的日志跨多天,需要区分不同日期的同一时间段,只需要修改主处理块的区间标识,把日期也加进去:
# 替换主处理块中的current_intv赋值部分 current_intv = $1 " " (hour >=0 && hour<4 ? "00-03" : \ hour>=4 && hour<8 ? "04-07" : \ hour>=8 && hour<12 ? "08-11" : \ hour>=12 && hour<16 ? "12-15" : \ hour>=16 && hour<20 ? "16-19" : "20-23") # 同时删掉BEGIN块中预定义intervals的代码,因为现在区间是动态生成的
这样输出的区间会变成类似2021-05-17 08-11的形式,完美区分不同日期的统计结果。
内容的提问来源于stack exchange,提问作者Vlad Nevskiy
相关产品推荐
相关产品推荐

