跳到主要内容

Linux grep 文本处理:查找、过滤与正则匹配

grep 用来在文本中按模式查找行。名字来自编辑器里的 g/re/p(global / regular expression / print)。写脚本、查日志、过滤命令输出时,它几乎是第一选择。

本章默认使用 GNU grep(常见于 Ubuntu / Debian)。命令手册也可参考 grep 命令

基本用法

grep [选项] 模式 [文件...]

从文件查找:

$ grep error app.log
2026-07-27 10:01:02 ERROR connection timeout

从管道查找:

$ dmesg | grep -i usb

模式里若含空格或 Shell 特殊字符,请加引号:

grep "connection refused" app.log

常用选项

选项作用
-i忽略大小写
-n显示行号
-v反向匹配(打印不匹配的行)
-c只输出匹配行数
-l只输出包含匹配的文件名
-r / -R递归搜索目录
-w按“整词”匹配
-x整行完全匹配
-o只输出匹配到的片段
-E使用扩展正则(ERE)
-F把模式当固定字符串,不做正则解释
-A N / -B N / -C N显示匹配行后/前/前后各 N 行上下文
# 忽略大小写,带行号
grep -in error app.log

# 递归查找 .sh 中的 TODO
grep -rn --include='*.sh' 'TODO' .

# 固定字符串,避免 . 被当成“任意字符”
grep -F '192.168.1.1' hosts.txt

与正则配合

默认 grep 使用基本正则(BRE)。需要 +?|() 时,加上 -E

# 匹配 error 或 warn
grep -E 'error|warn' app.log

# 提取 IPv4(简化)
grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log

正则基础见 正则表达式

在脚本中判断是否匹配

grep 找到匹配时退出码为 0,找不到为 1,出错为 2。因此可以直接用于 if

#!/bin/bash

if grep -q 'ERROR' app.log; then
echo "found errors"
else
echo "no error keyword"
fi

-q 表示安静模式:不打印匹配行,只返回状态码,适合脚本判断。

实用组合

统计匹配次数

grep -c 'ERROR' app.log

多文件中定位

grep -nH 'FIXME' *.sh

-H 强制打印文件名(多文件时默认就会打印)。

排除某些行

grep -E 'ERROR|WARN' app.log | grep -v 'known-issue'

配合 find

find . -name '*.conf' -print0 | xargs -0 grep -n 'Listen'

示例:过滤系统用户

/etc/passwd 中 shell 为 /usr/sbin/nologin/bin/false 的行常表示系统/服务账号:

grep -E '/(nologin|false)$' /etc/passwd

常见错误

现象原因与处理
模式里的 . 匹配了太多内容grep -F,或写成 \.
* 不符合预期你可能在用通配符思维;正则里 * 修饰前一个原子
脚本里明明有匹配却走进 else检查是否忘了引号,或工作目录不对
二进制文件被当成文本扫-I 忽略二进制,或限制 --include

下一章介绍专门做“查找并改写”的流编辑器 sed