您是否曾经面临在文件中查找特定字符串或模式的任务,却不知从何处着手?那么,grep 命令就是您的救星!
grep 是一个强大的文件模式搜索工具,它预装在每个 Linux 发行版中。如果出于某种原因,系统上未安装该工具,您可以通过包管理器轻松安装,具体操作如下:
sudo apt install grep [Debian, Ubuntu and Mint]
sudo yum install grep [RHEL/CentOS/Fedora and Rocky Linux/AlmaLinux]
sudo emerge -a sys-apps/grep [Gentoo Linux]
sudo apk add grep [Alpine Linux]
sudo pacman -S grep [Arch Linux]
sudo zypper install grep [OpenSUSE]
要快速上手 grep 命令,最简单的方法就是直接动手实践,使用一些实际案例。
grep [OPTION]... PATTERNS [FILE]...
上图只截取了一部分,完整的参数及选项请查看
--help
假设你刚刚在你的机器上全新安装了新的 Ubuntu,并且你打算尝试一下 Python 脚本编写。你一直在网上搜寻教程,但你发现使用了两个不同版本的 Python,你不知道 Ubuntu 安装程序默认安装了哪个版本的 Python,或者它是否安装了任何模块。
只需运行以下带有 grep 的 dpkg 命令,如下所示:
dpkg -l | grep -i python
首先,我们运行 dpkg -l,它列出系统上已安装的 *.deb 包。其次,我们将该输出通过管道(|)传递给 grep -i python,这简单地表示“去 grep 那里过滤并返回所有包含 'python' 的内容”。
-i 选项用于忽略大小写,因为 grep 是区分大小写的。养成使用 -i 选项的习惯是很好的,当然,除非你试图进行更具体的搜索。
2. 在 Linux 中搜索和过滤文件
grep 也可以用于在单个文件或多个文件中搜索和过滤。让我们看这个场景:你的 Apache Web 服务器遇到了一些麻烦,你向网上的大神寻求帮助。
回复你的好心人要求你发布 /etc/apache2/apache2.conf 文件的内容。如果你能删除所有注释行,这对你、帮助你的人以及所有阅读它的人来说是不是更容易?嗯,你可以!只需运行这个命令:
grep -v ^\# /etc/apache2/apache2.conf | grep .
-v 选项告诉 grep 反转其输出,这意味着不是打印匹配的行,而是做相反的操作,打印所有不匹配表达式的行,在这个例子中,就是那些以 # 开头的注释行。
请注意,我们还在末尾使用了 grep .,以便隐藏所有空行的输出。这样我们在终端中只看到配置设置。
3. 查找所有 .mp3 文件
grep 在过滤标准输出(stdout)时非常有用。假设你有一个装满各种格式音乐文件的文件夹。
你想找到歌手 唐伯虎Annie 的所有 *.mp3 文件,但你不想要任何混音版(remix)曲目。使用带有几个 grep 管道(pipe)的 find 命令可以完成这个任务:
find . -name "*.mp3" | grep -i 唐伯虎Annie | grep -vi "remix"

在这个例子中,我们使用 find 打印所有扩展名为 *.mp3 的文件,通过管道传递给 grep -i 来过滤并打印所有文件名包含 “唐伯虎Annie” 的文件,然后再通过管道传递给 grep -vi,它过滤掉不打印所有包含字符串(不区分大小写)“remix” 的文件名。
[ 你可能也喜欢:章节2:基本的Linux命令,【find】 命令的实用示例]
4. 显示搜索字符串之前或之后的行数
另外两个选项是 -A 和 -B 开关,它们显示匹配的行以及搜索字符串之前或之后的一定数量的行。
虽然手册页(man page)提供了更详细的解释,但我发现最容易记住这些选项的方法是:-A = after(之后),-B = before(之前):

ip a | grep -A 4 inet # 显示匹配行及其后4行
ip a | grep -B 2 UP # 显示匹配行及其前2行

5. 打印匹配行周围的行数
grep 的 -C 选项类似-A和-B,但它不是打印字符串之前或之后的行,而是打印两个方向的行:
ip a | grep -C 2 lo
6. 计算匹配次数
类似于将 grep 字符串通过管道传递给字数统计命令(wc 命令),grep 的内置选项 -c 可以为你执行相同的操作:
ip a | grep -c inet6 # 计算包含 "inet6" 的行出现了多少次
7. 按给定字符串在文件中搜索
在编译错误期间调试文件时,grep 的 -n 选项非常有用。它显示给定搜索字符串在文件中的行号:
grep -n "main" hello.py # 在 hello.py 文件中查找 "main" 并显示行号
8. 在所有目录中递归搜索字符串
如果你想在当前目录及其所有子目录中搜索一个字符串,可以指定 -r 选项进行递归搜索:
grep -r "hello" * # 在当前目录及子目录的所有文件中递归搜索 "hello"
file5.txt 是一个链接文件,链接的对象已经不在了,所以报错找不到。
9. 搜索整个模式
将 -w 选项传递给 grep 会搜索字符串中存在的整个模式(单词)。例如,使用:
ip a | grep -w "MUILTCAST" # 精确匹配单词 "RUNNING"
将会打印出包含引号中模式的行。另一方面,如果你尝试:
# ifconfig | grep -w "CAST" # 尝试精确匹配单词 "CAST" (可能不存在)
什么也不会返回,因为我们不是在搜索一个模式(子字符串),而是搜索一个完整的单词。
10. 在 Gzip 压缩文件中搜索字符串
值得提一下 grep 的一些衍生工具。第一个是 zgrep,它与 zcat 类似,用于处理 gzip 压缩的文件(*.gz)。它采用与 grep 相同的选项,并以相同的方式使用:
zgrep -i error /var/log/syslog.2.gz # 在压缩日志文件 syslog.2.gz 中搜索 "error" (忽略大小写)
11. 在文件中匹配正则表达式
egrep 命令是另一个衍生工具,代表 “Extended Global Regular Expression”(扩展全局正则表达式)。它识别额外的表达式元字符,如 +、?、| 和 ()。
egrep 命令在搜索源代码文件和其他代码片段时非常有用(如果需要的话)。它可以通过向常规 grep 指定 -E 选项来调用。
grep -E # 等同于使用 egrep
12. 搜索固定模式字符串
fgrep 命令在文件或文件列表中搜索固定模式字符串。它与 grep -F 相同。使用 fgrep 的一种常见方法是将一个包含模式的文件传递给它:
fgrep –f file_full_of_patterns.txt file_to_search.txt
这只是 grep 的一个起点,但正如你可能已经看到的,它在各种用途中都是非常宝贵的。除了我们实现的简单单行命令之外,grep 还可以用于编写强大的 cron 作业和健壮的 shell 脚本等。
场景 | 命令 | 作用 |
|---|---|---|
关键内容高亮 | grep --color=auto "key" | 匹配词红色突出 |
显示文件名 | grep -l "pattern" *.log | 只输出含匹配项的文件名 |
搜索二进制文件 | grep -a "text" data.bin | 避免漏搜二进制中的文本 |
多模式过滤 | grep -e "err" -e "fail" | 同时匹配多个关键词 |
grep "Gnome Display" file-r 默认跳过符号链接,-R 才会跟进链接文件alias grep='grep --color=auto' 加入 ~/.bashrc,永久高亮结果最后的建议: 当你能用
grep -C 5 "panic" /var/log/kern.log快速定位内核崩溃上下文时, 当你会用find /src -name "*.c" -exec grep -n "malloc" {} +揪出内存分配点时, 你就已从 grep 用户进化为 Linux 文本掌控者!