Linux 文本处理三剑客:grep 使用教程

介绍

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

五、多模式匹配

  1. 多个 -e 参数:多个匹配条件,满足任意一个即命中
grep -e "error" -e "timeout" app.log
  1. 从文件读取匹配规则(-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 家族区分

  1. grep:基础正则 BRE
  2. grep -E / egrep:扩展正则 ERE(推荐日常使用)
  3. grep -F / fgrep:纯字符串,​不解析正则​,搜索含 . * 等文本时避免转义麻烦

九、常见坑

  1. ​引号问题​:模式含 $,用双引号会被shell解析变量,正则尽量用单引号
  2. ​通配符不是正则​:shell 的 * 和 grep 正则 * 含义不一样
  3. -r 递归搜索二进制文件会输出大量乱码,可以加 --include 限定文件类型
# 只递归搜索 .log 文件
grep -r --include="*.log" "error" /var/log
# 排除 .gz 文件
grep -r --exclude="*.gz" "error" /var/log

原文出处:/show_1GW42glvI0hi.html