介绍
grep = Global Regular Expression Print,全局正则表达式打印,作用:从文件/管道输入中匹配文本行并输出。
语法
grep [选项] '匹配模式' [文件...]
准备文件
最终目录结构:
./test.txt
./logdir/app.log
创建测试文件 test.txt
复制下面全部内容,执行命令创建文件:
cat > test.txt <<'EOF'
2026-09-13 08:10:00 INFO user login, ip=192.168.1.100
2026-09-13 08:10:15 ERROR connect timeout, ip=192.168.1.101
2026-09-13 08:11:00 WARN disk usage 85%
2026-09-13 08:12:00 error: database disconnect
2026-09-13 08:13:00 INFO request finish
# 这是注释行
2026-09-13 08:14:00 ERROR mysql query failed
2026-09-13 08:15:00 test abc abcd abc123
hello world
HELLO LINUX
13800138000
13912345678
# 空行
EOF
创建测试文件 app.log
再创建一个子目录,放第二个测试文件,用来测试递归搜索:
mkdir logdir
cat > logdir/app.log <<'EOF'
2026-09-13 09:00:00 ERROR file not found
2026-09-13 09:01:00 INFO task start
EOF
一、基础用法
1. 在单个文件搜索关键词
grep "error" app.log
含义:输出文件中包含 error 的所有行。
简单字符串可以不加引号;含空格、特殊符号必须加单/双引号,正则推荐单引号
'pattern'。
2. 多个文件同时搜索
grep "warn" app.log nginx.log
3. 递归搜索目录下所有文件(重点)
grep -r "timeout" /var/log/
-r:递归,包含子目录-R:和-r基本一致,会跟随符号链接文件
二、常用选项
| 参数 | 作用 |
|---|---|
-i |
ignore,忽略大小写 |
-n |
line number,显示匹配行的行号 |
-v |
invert match,反向匹配:输出不匹配的行 |
-c |
count,只统计匹配行数,不输出内容 |
-o |
only-matching,只打印匹配到的字符串,不输出整行 |
-w |
word,整词匹配,不会匹配单词的一部分 |
-A N |
After,匹配行之后N行 |
-B N |
Before,匹配行之前N行 |
-C N |
Context,匹配行前后各N行(上下文) |
-q |
quiet,静默模式,只返回退出码,不输出任何内容 |
-e |
指定多个匹配模式,支持以 -e pattern1 -e pattern2 |
-F |
fixed-strings,把模式当作普通字符串,禁用正则(速度快) |
示例:
# 忽略大小写,显示行号,搜索 error
grep -in "error" app.log
# 反向匹配:过滤掉空行
grep -v "^$" test.txt
# 统计包含 fail 的行数
grep -c "fail" app.log
# 匹配行以及前后各3行日志
grep -C3 "Exception" app.log
# 整词匹配,匹配 abc,不会匹配 abcd
grep -w "abc" test.txt
三、正则表达式用法
grep 默认支持基础正则BRE;grep -E 使用扩展正则ERE(推荐,不用大量反斜杠转义)
grep -E等价于egrep
基础元字符
| 符号 | 含义 |
|---|---|
. |
任意单个字符(不能匹配换行) |
* |
前面字符重复0次或多次 |
^ |
行开头 |
$ |
行结尾 |
[] |
字符集 [0-9] [a-z] |
[^] |
取反字符集 |
扩展正则(-E)新增
| 符号 | 含义 |
|---|---|
+ |
前面字符至少1次 |
? |
前面字符0次或1次 |
| |
或 |
() |
分组 |
{m,n} |
重复次数 m~n次 |
示例:
# 匹配以 http 开头的行
grep -E '^http' test.txt
# 匹配以 .com 结尾的行
grep -E '\.com$' test.txt
# 匹配 error 或者 warn
grep -E 'error|warn' app.log
# 匹配手机号 1开头,后面10位数字
grep -E '1[0-9]{10}' data.txt
⚠️ 注意:
.*()|在基础正则里需要加\转义,所以写复杂正则优先用 grep -E
四、管道结合 grep
grep 可以接收管道输入,过滤命令输出:
# 查看进程,过滤 nginx
ps -ef | grep nginx
# 查看端口,过滤8080
netstat -tulpn | grep 8080
# 新版推荐 ss
ss -tulpn | grep 8080
# 查看磁盘,过滤 /dev/sda
df -h | grep sda
小坑:
ps | grep xxx结果会包含 grep 自身进程。 解决:ps -ef | grep [n]ginx
五、多模式匹配
- 多个
-e参数:多个匹配条件,满足任意一个即命中
grep -e "error" -e "timeout" app.log
- 从文件读取匹配规则(
-f)
# pattern.txt 每行写一个关键词
grep -f pattern.txt app.log
六、退出码
0:找到匹配内容1:没有找到匹配2:命令出错(文件不存在等)
静默模式脚本示例:
if grep -q "root" /etc/passwd;then
echo "root 用户存在"
fi
七、常见实战案例
1. 过滤日志,排除注释行(#开头)
grep -v '^#' nginx.conf
2. 查找文件中空白行
grep '^$' test.txt
3. 递归搜索代码,找到包含 return 的文件,显示行号
grep -rn "return" /home/code/
4. 只提取所有IP地址
grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log
八、grep 家族区分
grep:基础正则 BREgrep -E/egrep:扩展正则 ERE(推荐日常使用)grep -F/fgrep:纯字符串,不解析正则,搜索含. *等文本时避免转义麻烦
九、常见坑
- 引号问题:模式含
$,用双引号会被shell解析变量,正则尽量用单引号 - 通配符不是正则:shell 的
*和 grep 正则*含义不一样 -r递归搜索二进制文件会输出大量乱码,可以加--include限定文件类型
# 只递归搜索 .log 文件
grep -r --include="*.log" "error" /var/log
# 排除 .gz 文件
grep -r --exclude="*.gz" "error" /var/log