You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

日志无精确时间戳时如何用awk筛选日期范围值并统计计数

日志指定时间范围AAA-passed计数实现方案

问题描述

需要从固定格式的日志中统计指定时间区间内AAA-passed类型的记录条数,日志样例如下:

# values.log 文件内容
2022-01-01-10:01 AAA-passed
2022-01-01-11:05 AAA-passed
2022-01-01-12:01 AAA-passed
2022-01-01-13:05 AAA-passed
2022-01-02-12:01 AAA-failed
2022-01-03-13:05 AAA-failed

最初使用的awk区间匹配写法,依赖日志中存在与起止时间完全一致的精确时间戳,当日志中不存在传入的起止时间点时,会返回错误统计结果。原问题代码如下:

t1='2022-01-01-10:01'
t2='2022-01-03-13:05'

pass=$(awk '/^'$t1.*'/,/'$t2.*'/' values.log | grep -w "AAA-passed" | wc -l)
echo $pass

例如传入t1='2022-01-01-10:00'、t2='2022-01-03-14:00'时,由于日志中不存在这两个精确时间点,上述命令无法得到正确结果。

实现步骤

找到的非精确匹配awk脚本依赖固定时间格式,且不支持动态传参,按以下两步修改即可满足需求:

1. 调整时间生成格式

不需要硬套参考脚本里的年-月-日 时:分:秒.毫秒格式,你的日志时间前缀为年-月-日-时:分,该格式的字符串字典序和实际时间先后顺序完全一致,可以直接做大小比对,只需要让date生成和日志时间前缀格式一致的起止时间即可:

# 生成7天前到当前时刻的起止时间,格式与日志时间前缀完全匹配
t1=$(date -d "${dtd} -7 days" +'%Y-%m-%d-%H:%M')
t2=$(date '+%Y-%m-%d-%H:%M')

2. 改造awk脚本完成统计

通过awk的-v参数传入动态生成的起止时间,在awk内部同时完成时间范围判断和目标记录计数,不需要额外嵌套grep、wc命令:

pass=$(awk -v start="$t1" -v end="$t2" '
# 匹配符合时间格式开头的有效日志行
/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}:[0-9]{2}/ {
    # 截取每行前16位的时间戳部分
    ts = substr($0, 1, 16)
    # 判断当前行是否在指定时间范围内
    inrange = ts >= start && ts <= end
}
# 时间范围内且为AAA-passed的行累计计数
inrange && /AAA-passed/ {
    count++
}
# 所有行处理完成后输出计数结果,无匹配时输出0
END {
    print count + 0
}
' values.log)

echo $pass

方案特性

  • 不依赖起止时间点在日志中存在,只要日志行时间戳落在[start, end]闭区间内就会被统计
  • 时间比对直接用字符串字典序实现,不需要转unix时间戳,逻辑简单执行效率高
  • 所有逻辑在单个awk进程中完成,减少管道嵌套的性能开销
  • 无匹配记录时默认返回0,不会出现空值
  • 测试验证:传入t1='2022-01-01-10:00'、t2='2022-01-03-14:00'时,统计结果为4,与预期一致。

内容的提问来源于stack exchange,提问作者Kasun Wimaladarma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 10:18:05