Skip to content

grep ​

grep(Global Regular Expression Print)在文件或标准输入中搜索匹配正则表达式的行并输出。

基本语法 ​

bash
grep [选项] 模式 [文件...]
grep [选项] -e 模式1 -e 模式2 [文件...]
grep [选项] -f 模式文件 [文件...]

常用选项 ​

选项说明
-i忽略大小写
-v反向匹配(输出不匹配的行)
-n显示行号
-c只输出匹配行数
-l只输出包含匹配的文件名
-L只输出不包含匹配的文件名
-r / -R递归搜索目录
-w全词匹配
-x全行匹配
-q静默模式,不输出任何内容(只返回退出码)
-o只输出匹配部分
-h多文件时不输出文件名
-H始终输出文件名
-m N最多输出 N 行匹配
--color高亮匹配内容

上下文选项 ​

选项说明
-A N匹配行之后 N 行(After)
-B N匹配行之前 N 行(Before)
-C N匹配行前后各 N 行(Context)
bash
grep -A3 "ERROR" app.log       # 错误行及后3行
grep -B2 "FATAL" app.log       # 致命错误行及前2行
grep -C2 "timeout" app.log     # 超时行前后各2行

正则表达式 ​

基本正则(BRE,默认) ​

元字符含义
.任意单个字符
*前一个字符 0 次或多次
^行首
$行尾
[]字符类
\转义
bash
grep "^root" /etc/passwd        # root 开头的行
grep "bash$" /etc/passwd        # bash 结尾的行
grep "f.o" file.txt             # f 和 o 之间有任意字符
grep "[0-9]\{3\}" file.txt      # BRE 重复 3 次

扩展正则(ERE,使用 -E 或 egrep) ​

元字符含义
+1 次或多次
?0 或 1 次
{n,m}重复次数范围
|或(ERE 中用 |,BRE 中不支持)
()分组
bash
grep -E "error|warn|fatal" app.log        # 多模式或
grep -E "^[0-9]{1,3}\.[0-9]{1,3}" file   # IP 地址前缀
grep -E "https?://" file.txt              # http 或 https
grep -E "(foo|bar)baz" file.txt           # 分组

Perl 兼容正则(PCRE,使用 -P) ​

bash
grep -P "\d{4}-\d{2}-\d{2}" log.txt       # 日期格式
grep -P "(?<=:)\d+" /etc/passwd            # 后向断言
grep -P "\bword\b" file.txt                # 单词边界

多模式搜索 ​

bash
# -e 指定多个模式
grep -e "error" -e "warning" app.log

# -f 从文件读取模式(每行一个)
grep -f patterns.txt app.log

递归搜索 ​

bash
# 递归搜索目录
grep -r "TODO" ./src/

# 递归搜索并显示文件名和行号
grep -rn "malloc" /usr/include/

# 只搜索指定扩展名文件
grep -r --include="*.py" "import os" ./

# 排除目录或文件
grep -r --exclude-dir=".git" --exclude="*.min.js" "pattern" ./

实用示例 ​

bash
# 查找包含某字符串的文件名(不显示内容)
grep -rl "debug" /var/log/

# 统计匹配行数
grep -c "ERROR" app.log

# 反向过滤(去掉注释行和空行)
grep -v "^#" /etc/fstab | grep -v "^$"

# 查看进程(排除 grep 自身)
ps aux | grep "[n]ginx"

# 提取 IP 地址
grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log

# 统计各 HTTP 状态码数量
grep -Eo ' [0-9]{3} ' access.log | sort | uniq -c | sort -rn

# 查找二进制文件中的字符串
grep -a "Copyright" binary_file

# 只输出匹配的部分(-o)
grep -o "user=[^&]*" url.log

退出状态 ​

退出码含义
0找到至少一个匹配
1没有匹配
2发生错误
bash
# 在脚本中判断是否存在某配置
if grep -q "^PermitRootLogin yes" /etc/ssh/sshd_config; then
    echo "root login enabled"
fi

grep 变体 ​

命令等价说明
egrepgrep -E扩展正则
fgrepgrep -F固定字符串(不解析正则,更快)
rgrepgrep -r递归搜索
zgrep—搜索 gzip 压缩文件