查找日志文件中最后一次出现某个关键词的上下 20 行
方法 1:使用 grep
+ tac
+ sed
(推荐)
tac logfile | grep -m1 -A20 -B20 "your_keyword" | tac
- 原理:
tac
反向读取日志(从最后一行开始)。grep -m1
只匹配第一次出现的关键词(即原日志的最后一次)。-A20 -B20
显示匹配行的前后 20 行。- 再次
tac
恢复原始顺序。
示例:
tac /var/log/nginx/error.log | grep -m1 -A20 -B20 "error" | tac
方法 2:使用 awk
记录匹配行号并提取
awk '/your_keyword/ {last_match=NR} END {if (last_match) print last_match}' logfile | xargs -I{} awk 'NR>={}-20 && NR<={}+20' logfile
- 原理:
awk
记录最后一次匹配的行号last_match
。xargs
传递行号,再次用awk
提取last_match ± 20
行。
示例:
awk '/error/ {last_match=NR} END {if (last_match) print last_match}' /var/log/syslog | xargs -I{} awk 'NR>={}-20 && NR<={}+20' /var/log/syslog
方法 3:使用 sed
直接提取(适合小文件)
line=$(grep -n "your_keyword" logfile | tail -1 | cut -d: -f1) && \
sed -n "$((line>20 ? line-20 : 1)),$((line+20))p" logfile
- 原理:
grep -n
获取所有匹配行号,tail -1
取最后一次。sed -n "a,bp"
打印从a
到b
的行(自动处理边界情况)。
示例:
line=$(grep -n "failed" app.log | tail -1 | cut -d: -f1) && \
sed -n "$((line>20 ? line-20 : 1)),$((line+20))p" app.log
方法 4:使用 less
交互式查找(适合手动检查)
less +?"your_keyword" logfile
- 操作步骤:
- 按
n
跳转到最后一个匹配项。 - 按
-20j
向上滚动 20 行,+20j
向下滚动 20 行。
- 按
注意事项
- 大文件优化:
如果日志文件很大(如 GB 级),优先使用tac
或awk
方法,避免全文件扫描。 - 边界处理:
如果匹配行靠近文件开头(行号<20
),上述命令会自动调整范围。 - 时间戳辅助:
如果日志带时间戳,可以先定位时间范围再过滤:grep -A20 -B20 "your_keyword" logfile | tail -41 # 近似最后匹配的±20行
终极方案:结构化日志(如 JSON)
如果日志是 JSON 格式,用 jq
更精准:
tac log.json | jq -c 'select(.msg | contains("error"))' | head -1 | jq . | tac
选择最适合你日志格式的方法即可!