Shell正则需依托grep、sed等工具实现日志筛选,关键在于区分BRE与ERE语法:grep默认BRE(+?|需转义),-E启用ERE;sed同理,-r(GNU)或-E(macOS)启用ERE;组合管道与注意系统兼容性可提升效率。

Shell中正则表达式本身不独立存在,而是通过工具(如 grep、sed)调用实现日志筛选。关键在于掌握各工具对正则的支持差异和常用写法,避免因语法不兼容导致匹配失败。
grep:基础匹配与扩展正则切换
grep 默认使用基本正则(BRE),元字符如 +、?、| 需加反斜杠才生效;而 grep -E(或 egrep)启用扩展正则(ERE),可直接使用这些符号。
- 匹配含“ERROR”且后跟数字的日志行:
grep 'ERROR[0-9]\+' /var/log/app.log(BRE) - 等价的 ERE 写法:
grep -E 'ERROR[0-9]+' /var/log/app.log - 匹配 IP 地址(简化版):
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/nginx/access.log
sed:边匹配边编辑,适合提取与替换
sed 默认也是 BRE,但支持 -r(GNU sed)或 -E(macOS/BSD sed)启用 ERE。常用于提取字段、脱敏、过滤行。
- 提取日志中的时间戳(假设格式为
[2024-05-12 10:23:45]):sed -n 's/^\[\([^]]*\)\].*/\1/p' app.log - 删除含“DEBUG”的整行:
sed '/DEBUG/d' app.log - 将所有手机号替换为
***(简单模式):sed -E 's/[0-9]{11}/***/g' app.log
实际日志筛选组合技巧
单个工具能力有限,组合使用更高效。注意管道顺序和引号使用,防止 shell 提前解析特殊字符。
- 查最近1小时的 ERROR 日志(配合
awk时间判断):awk -F'[][]' '$2 > strftime("%Y-%m-%d %H:%M:%S", systime()-3600)' app.log | grep -E 'ERROR|FATAL' - 统计不同 HTTP 状态码出现次数:
grep -oE 'HTTP/1\.1 [0-9]{3}' access.log | awk '{print $2}' | sort | uniq -c - 排除注释与空行后再匹配关键字:
grep -vE '^[[:space:]]*#|^$' config.conf | grep 'listen_port'
避坑提醒:常见不兼容点
不同系统、不同版本的工具对正则支持不一,尤其在 macOS 和 Linux 间容易出错。
- macOS 的
sed不支持-r,必须用-E;Linux GNU sed 两者都支持 -
grep的-o(仅输出匹配部分)在旧版 BusyBox 中可能缺失 - 字符类如
[[:digit:]]比[0-9]更安全,避免 locale 导致范围异常 - 量词
{n,m}在 BRE 中需转义:\{2,5\},ERE 中直接写{2,5}

















