🔍搜索⌘K

Linux 下 Grep 命令基础使用指南:高效文本搜索利器

概述

Grep(Global Regular Expression Print,全局正则表达式打印)是 Linux 下最核心的文本搜索工具,干的活就是在文件或者输入流里找出匹配某个模式(字符串 / 正则表达式)的行,然后输出出来。它不光能搞简单的字符串匹配,配合正则表达式还能做复杂的文本筛选,是日常运维、开发调试、日志分析里离不开的工具。

按 Man 手册的说法,Grep 的核心作用就是 “print lines that match patterns”(把匹配模式的行打出来),它的优势在这几方面:

  1. 高效:轻量级工具,就算处理 GB 级的大日志,响应也很快;
  2. 灵活:支持正则表达式、忽略大小写、结果过滤等各种高级玩法;
  3. 通用:能跟 cat、find、ps 这些命令用管道(|)串起来,搞出复杂的文本处理流程。

这篇文章从 “基础匹配” 讲到 “高级筛选”,把 Grep 最常用的场景和命令都梳理一遍,帮你快点掌握高效的文本搜索技巧。

一、Grep 核心用法:从基础到高级

Grep 的基本语法是 grep [选项] “匹配模式” [文件/路径],“匹配模式” 可以是普通字符串也可以是正则表达式,“文件 / 路径” 指定要搜的目标(不指定的话,默认从标准输入读,比如管道传进来的内容)。下面按 “常用场景” 分门别类给例子,每个场景都带命令、说明和用法。

1. 基础搜索:显示匹配内容并高亮

场景:在文件中搜索指定字符串,并高亮显示匹配部分

# 基本语法:grep --color "匹配字符串" 目标文件
grep --color "error" /var/log/syslog

说明:

  • —color:把匹配到的字符串用颜色高亮出来(不同终端默认高亮色不一样,一般是红色,方便一眼定位);
  • 如果系统默认就开了高亮(有些 Linux 发行版配了别名),—color 可以省掉,直接 grep "error" /var/log/syslog 就行;
  • 支持多文件一起搜,比如 grep --color "error" /var/log/syslog /var/log/messages(同时搜两个日志文件)。

场景扩展:从标准输入里搜(配合管道)

# 示例:先看文件内容,再用 Grep 筛出含 "error" 的行
cat /var/log/syslog | grep --color "error"

# 示例:看进程列表,筛出含 "nginx" 的进程
ps aux | grep --color "nginx"

2. 结果过滤:排除不需要的内容

场景 1:排除包含指定字符串的行(反向匹配)

# 基本语法:grep -v "排除字符串" 目标文件
# -v(--invert-match):反向匹配,只输出不包含 "排除字符串" 的行
grep -v "info" /var/log/syslog
# 作用:在系统日志中,排除含 "info"(普通信息)的行,只显示警告/错误等关键内容

场景 2:排除多个指定字符串的行

# 基本语法:grep -vE "字符串1|字符串2" 目标文件
# -E(--extended-regexp):启用扩展正则表达式,支持 "|"(或)逻辑
grep -vE "info|debug" /var/log/syslog
# 作用:排除含 "info" 或 "debug" 的行,只保留 "warn"、"error" 等重要日志

场景 3:排除空行或仅含空格的行

# 基本语法:grep [^[:space:]] 目标文件
# [^[:space:]]:正则表达式,表示 "不包含任何空白字符(空格、制表符等)的行"
grep [^[:space:]] config.ini
# 作用:过滤配置文件中的空行和仅含空格的行,只显示有效配置项

3. 结果增强:显示行号、仅取匹配内容

场景 1:显示匹配行的行号(方便定位文件位置)

# 基本语法:grep -n "匹配字符串" 目标文件
# -n(--line-number):在输出结果前加上匹配行的行号
grep -n "port" /etc/nginx/nginx.conf
# 输出示例:15:    listen 80; (表示第 15 行包含 "port")
# 作用:修改配置文件时,快速定位匹配内容的行号

场景 2:仅显示匹配的字符串(而非整行)

# 基本语法:grep -o "匹配字符串" 目标文件
# -o(--only-matching):只输出匹配到的字符串本身,不显示整行内容
grep -o "([0-9]\{3\})[0-9]\{3\}-[0-9]\{4\}" contacts.txt
# 作用:从联系人文件中提取所有符合 "XXX-XXX-XXXX" 格式的电话号码(结合正则)

4. 搜索范围:递归搜索与指定文件

场景 1:递归搜索目录下所有文件(含子目录)

# 基本语法:grep -R "匹配字符串" 目标目录
# -R(--recursive):递归搜索指定目录下的所有文件(包括子目录中的文件)
# (部分系统支持 -r,与 -R 功能一致)
grep -R "import pandas" /home/user/projects/
# 作用:在项目目录中,递归搜索所有含 "import pandas" 的 Python 文件(.py)

场景 2:仅搜索指定类型的文件(如 .log、.py)

# 基本语法:grep --include="文件类型" "匹配字符串" 目标目录
# --include:仅搜索符合 "文件类型" 的文件(支持通配符,如 *.log、*.py)
grep -R --include="*.log" "error" /var/log/
# 作用:在 /var/log 目录下,仅递归搜索所有 .log 日志文件中的 "error" 行

场景 3:排除指定类型的文件(如 .git、.tmp)

# 基本语法:grep --exclude="文件类型" "匹配字符串" 目标目录
# --exclude:搜索时排除符合 "文件类型" 的文件
grep -R --exclude="*.git" "function" /home/user/projects/
# 作用:在项目目录中递归搜索 "function",但排除 .git 后缀的版本控制文件

5. 结果简化:仅显示文件名或静默判断

场景 1:仅显示包含匹配内容的文件名(而非具体行)

# 基本语法:grep -l "匹配字符串" 目标文件/目录
# -l(--files-with-matches):只输出 "包含匹配内容的文件路径",不显示具体匹配行
grep -l "error" /var/log/*.log
# 输出示例:/var/log/syslog、/var/log/messages(表示这两个文件含 "error")
# 作用:批量排查哪些文件包含目标内容(如找出所有含错误日志的文件)

场景 2:静默搜索(仅判断是否存在匹配,不输出内容)

# 基本语法:grep -q "匹配字符串" 目标文件
# -q(--quiet/--silent):静默模式,不输出任何内容,仅通过退出码判断是否匹配
# 退出码规则:0 = 存在匹配,1 = 不存在匹配,2 = 文件不存在
grep -q "nginx" /etc/init.d/*
if [ $? -eq 0 ]; then
  echo "找到 nginx 启动脚本"
else
  echo "未找到 nginx 启动脚本"
fi
# 作用:在脚本中判断文件是否包含指定内容(如自动化部署时检查配置)

6. 正则匹配:锚定单词与复杂模式

场景:精确匹配完整单词(避免部分匹配)

比如搜 “world” 的时候,不想匹配到 “worldwide”、“helloworld” 这种里面带 world 但不是完整单词的情况:

# 方法 1:用 \< 和 \> 锚定单词边界
grep --color "\<world\>" test.txt

# 方法 2:用 \b 锚定单词边界(与 \<\> 功能一致,更简洁)
grep --color "\bworld\b" test.txt

说明:

  • <:匹配单词的开头边界(单词前面没有别的字母 / 数字 / 下划线);
  • >:匹配单词的结尾边界(单词后面没有别的字母 / 数字 / 下划线);
  • \b:同时代表单词的开头或结尾边界,是 < 和 > 的简写,更省事。

7. 上下文显示:查看匹配行的前后内容

分析日志时,经常得看 “匹配行的上下文”(比如报错前后的样子),Grep 提供了 -A(后)、-B(前)、-C(前后)三个参数来干这事:

场景 1:显示匹配行及其后 N 行

# 基本语法:grep -A N "匹配字符串" 目标文件
# -A(--after-context=N):A = After,显示匹配行及其后面 N 行的内容
grep -A 2 "error" /var/log/syslog
# 作用:显示含 "error" 的行,以及该行后面 2 行的内容(查看错误后续的日志)

场景 2:显示匹配行及其前 N 行

# 基本语法:grep -B N "匹配字符串" 目标文件
# -B(--before-context=N):B = Before,显示匹配行及其前面 N 行的内容
grep -B 3 "error" /var/log/syslog
# 作用:显示含 "error" 的行,以及该行前面 3 行的内容(查看错误发生前的日志)

场景 3:显示匹配行及其前后各 N 行

# 基本语法:grep -C N "匹配字符串" 目标文件
# -C(--context=N):C = Context,显示匹配行及其前后各 N 行的内容(等价于 -A N -B N)
grep -C 2 "error" /var/log/syslog
# 作用:显示含 "error" 的行,以及该行前后各 2 行的内容(完整查看错误上下文)

###8. 大小写忽略:不区分大小写的匹配

场景:搜索时忽略字符串的大小写(如同时匹配 “Error”、“ERROR”、“error”)

# 基本语法:grep -i "匹配字符串" 目标文件
# -i(--ignore-case):忽略大小写,匹配所有大小写组合的字符串
grep -i "error" /var/log/syslog
# 输出示例:同时显示含 "error"、"Error"、"ERROR" 的行
# 作用:日志中错误信息可能有不同大小写,避免遗漏匹配

二、常用组合命令:Grep 与其他工具搭配

Grep 经常跟别的 Linux 命令用管道(|)串起来,实现更复杂的文本处理,下面都是高频组合:

1. 结合 Find:搜索指定目录下的特定文件

# 示例:在 /home/user 目录下,查找所有 .txt 文件,并搜索含 "hello" 的行
find /home/user -name "*.txt" | xargs grep --color "hello"
# 说明:find 找到所有 .txt 文件,xargs 将文件列表传递给 grep 进行搜索

2. 结合 Sort + Uniq:统计匹配结果的去重计数

# 示例:从日志中提取所有 IP 地址,统计每个 IP 的出现次数(去重并排序)
grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" access.log | sort | uniq -c | sort -nr
# 说明:
# 1. grep -o 提取所有 IP 地址;
# 2. sort 排序 IP 地址,便于 uniq 去重;
# 3. uniq -c 统计每个 IP 的出现次数;
# 4. sort -nr 按次数倒序排列(从多到少)

3. 结合 Head/Tail:查看匹配结果的前 N 行 / 后 N 行

# 示例:在日志中搜索 "error",只查看前 5 条结果
grep --color "error" /var/log/syslog | head -n 5

# 示例:在日志中搜索 "error",只查看后 3 条结果
grep --color "error" /var/log/syslog | tail -n 3

三、注意事项(避坑指南)

  1. 特殊字符要转义:如果匹配模式里包含正则特殊字符(比如 .、*、?、|),得用反斜杠(\)转义,不然 Grep 会把它当成正则语法去解析。 例子:搜 “192.168.1.1” 时,得写成 grep "192\.168\.1\.1" access.log(把 . 转义成 .,否则 . 会匹配任意字符)。
  2. 空格和引号:如果匹配模式带空格(比如 “error code”),必须用双引号(“)或单引号(‘)包起来,不然 Grep 会把空格后面的内容当成 “目标文件”。 正确:grep "error code" syslog;错误:grep error code syslog(会把 “code” 当成文件名)。
  3. 区分 -R 和 -r:大部分 Linux 发行版里 -R 和 -r 一样(都是递归搜索),但有些老系统只认 -R,所以优先用 -R 更稳妥。
  4. 大文件处理:搜 GB 级大文件时,建议加上 —line-buffered 参数(比如 grep --line-buffered "error" large.log),免得 Grep 缓存太多内容导致响应变慢。

总结

Grep 是 Linux 文本处理里的 “多面手”,核心价值就是 “精准、高效地筛文本”。这篇文章整理的命令覆盖了日常 90% 的使用场景,从基础的 “字符串搜索” 到高级的 “正则匹配 + 上下文显示”,再到跟其他工具组合,应付日志分析、配置检查、代码搜索都够了。

新手建议先从 “基础搜索 + 高亮""显示行号""递归搜索” 这三个场景练起,慢慢熟悉正则表达式和参数组合;进阶之后可以玩玩 Grep 的扩展工具(比如 egrep 等价于 grep -E、fgrep 等价于 grep -F,后者用来匹配固定字符串),文本处理效率还能再上一层。