这个场景解决什么
排查某时段故障时,第一步往往是把日志缩小到那个时间窗。sed 适合按「起止模式」截取一段,awk 适合按时间字段做区间比较,journalctl 则自带时间参数。三条路各有适用面:日志里的时间在同一行内用 awk 更准,跨行标记用 sed 更省事,系统日志直接用 journalctl 最方便。
基本信息
| 场景 | 从大日志中提取指定时间段的内容 |
|---|---|
| 三种手段 | sed 模式区间、awk 字段比较、journalctl 时间参数 |
| 前提 | 先确认日志的时间字段位置与格式,是否定长 |
| 效率建议 | 先用 grep 按日期把文件缩到当天,再做时间区间过滤 |
典型使用场景
- 故障复盘:只提取故障发生前后十分钟的日志,避免被无关内容淹没
- 变更验证:提取发布时刻前后的记录,确认改动生效与副作用
- 统计核对:统计某时段内的错误条数,与监控告警对账
- 跨天排查:处理跨越零点的时间窗,避免只看单日文件
- 日志切片:把关键时段导出成小文件,方便转交与二次分析
sed 按起止模式截取
sed 按起止模式截取
sed -n '/2026-10-12 10:00/,/2026-10-12 10:05/p' app.log | head -100
sed -n '/10:00:00/,/10:05:59/p' app.log | wc -l
sed -n '/====== START/,/====== END/p' app.log | head # 日志里自带的分段标记awk 按时间字段比较
awk 按时间字段比较
head -n 3 app.log # 先确认时间字段在第几列
awk -v s='10:00:00' -v e='10:05:59' '$2>=s && $2<=e' app.log | head
awk '$1=="2026-10-12" && $2 >= "10:00:00"' app.log | wc -l
awk -F'[][]' -v s='12/Oct/2026:10:00:00' -v e='12/Oct/2026:10:05:59' '$2>=s && $2<=e' access.log | head
grep '^2026-10-12' app.log | awk -v s='10:00:00' '$2>=s' | head # 先缩范围再过滤系统日志场景
系统日志场景
journalctl --since '2026-10-12 10:00:00' --until '2026-10-12 10:06:00'
journalctl --since '1 hour ago' -u myapp --no-pager | head
journalctl --since today -p err -o short-iso | head方案对照
| 方案 | 适用 | 局限 |
|---|---|---|
| sed 起止模式 | 日志里有明确起止标记,或按文本时间截段 | 只在首次匹配的区间内取值,多次出现需分段处理 |
| awk 字段比较 | 时间字段定长且可比 | 格式不定长或时区不统一时会漏记录 |
| journalctl 时间参数 | systemd 管理的系统与服务日志 | 只对 journal 里的日志有效 |
| grep 前缀再加 awk | 大文件先缩小范围 | 需要日志开头带日期前缀 |
先用 grep 把范围缩到单日,再做时间区间过滤,速度通常有明显提升,因为后续处理的数据量小了一个数量级。
awk 的字符串比较要求时间格式定长且同构:带前导零与不带前导零的混在一起比较会得出错误结果。动手前先 head 几行确认格式。