如何对同一文件实现多模式grep匹配 命中任意模式即触发操作
多模式日志搜索脚本实现方案
基础改造(匹配任意模式即触发原有逻辑)
原有脚本仅支持匹配ERROR:关键词,核心原因是grep语句写死了单个匹配规则。最简便的改造方式是利用grep原生的多模式匹配能力,仅扫描一次日志文件即可命中所有指定关键词,不会额外增加IO开销。
改造步骤:
- 单独抽离需要匹配的模式列表作为配置项,后续新增、删除匹配关键词时不需要改动核心逻辑
- 替换原有单关键词grep语句,通过扩展正则参数一次匹配所有定义的模式
- 完全保留原有的新旧日志差分逻辑,不影响原有告警触发流程
改造后可直接运行的完整代码:
#!/bin/bash # 匹配模式配置,多个模式用|分隔即可,新增模式直接在后面追加 MATCH_PATTERNS="ERROR:|PANIC:|FATAL:" newlog=PG_messages_${day}.new oldlog=PG_messages_${day}.old log=postgresql-${day}.log touch ${newlog} ${oldlog} mv ${newlog} ${oldlog} # 加-E参数开启扩展正则支持,一次匹配所有目标模式 grep -E "${MATCH_PATTERNS}" $log > $newlog 2>&1 diff $newlog $oldlog 1>/dev/null 2>&1 if [ $? -ne 0 ]; then diff $newlog $oldlog >> /tmp/$$ cat /tmp/$$ # 可在此处追加后续告警动作,比如调用消息推送接口 fi
提示:如果要匹配的关键词中包含正则特殊字符(比如
.、*、?、[等),需要在字符前加\转义,避免出现不符合预期的匹配结果。
进阶改造(不同模式触发差异化操作)
如果后续需要针对不同级别的日志执行不同操作(比如匹配到PANIC:触发紧急电话告警,匹配到ERROR:触发普通群消息通知),可以先通过grep批量筛选出所有命中的日志行,再做分级判断,兼顾性能和灵活性,参考实现:
#!/bin/bash MATCH_PATTERNS="ERROR:|PANIC:|FATAL:" log=postgresql-${day}.log panic_logs=$(mktemp) error_logs=$(mktemp) # 先批量筛出所有命中规则的日志 all_match_logs=$(grep -E "${MATCH_PATTERNS}" "$log") # 再对不同级别日志做拆分处理 echo "$all_match_logs" | grep "PANIC:" > "$panic_logs" echo "$all_match_logs" | grep "ERROR:" > "$error_logs" # 针对PANIC日志执行高优操作 if [ -s "$panic_logs" ]; then echo "检测到PANIC级严重日志:" cat "$panic_logs" # 此处加紧急告警逻辑 fi # 针对ERROR日志执行普通操作 if [ -s "$error_logs" ]; then echo "检测到ERROR级错误日志:" cat "$error_logs" # 此处加普通告警逻辑 fi # 清理临时文件 rm -f "$panic_logs" "$error_logs"
注意:如果日志文件体量超过1G,不建议用shell逐行read遍历的方式做匹配,性能会远低于grep批量筛选方案。
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

