这篇文章总结下 grep 命令的常用方法。
1. 需求背景
平时在使用 Linux 过程中,总会遇到需要搜索某个字符串的场景:
- 搜索某个字符串是否出现在指定文件中;
- 利用管道重定向,搜索
ls、cat等命令的输出中是否包含某个字符串; - 递归搜索某个工程目录下的所有文件中,是否包含某个字符串。
grep 无疑是很好用且功能强大的工具之一。
2. 使用方法
grep 的搜索是按行进行的,即:每次扫描一行,如果该行中包含指定的字符串,那么该行会被输出。
2.1 基本用法
grep 最基本的用法如下:
1 | grep <搜索字符串> <搜索的目标文件> |
举个例子:我们要搜索 hello_world.c 文件中是否包含 hello 这个字符串,可以这么做:
1 | grep 'hello' hello_world.txt |
我们也可以利用输出重定向和管道完成这件事情:
1 | cat hello_world.c | grep 'hello' |
*注 1:grep 后面跟的 <搜索字符串> 可以加单引号 '',也可以加双引号 "",也可以什么都不加。当然还是建议使用引号将其包住,这样能方便命令的阅读。
*注 2:现在的 shell 基本都包含了 alias grep='grep --color=auto' 可以通过 alias -p 查看。所以在使用 grep 搜索时,不需要带上 --color=auto 参数,搜索匹配到的关键字还是会用不同颜色显示出来。
*注 3:grep 命令对搜索字符串的大小写敏感。
2.2 -i 参数
-i 参数里面的 i 表示英文单词 ignore,意思是搜索时忽略大小写,因为 grep 本身对大小写是敏感的。
1 | grep -i 'hello' hello_world.txt |
那么,hello_world.txt 文件中所有的 hello 、HELLO、HeLLo 等均会被检索出来。
2.3 -v 参数
-v 参数表示 反向搜索,意思是:将那些不包含 <搜索字符串> 的行输出:
1 | grep -v 'hello' hello_world.txt |
那么,hello_world.txt 文件中不包含 hello 字符串的行将会被输出。
2.4 -n 参数
-n 参数会将满足 <搜索字符串> 的行对应的行数也输出来:
1 | grep -n 'hello' hello_world.txt |
输出:
1 | ubuntu@VM-0-14-ubuntu:~$ grep -n 'hello' hello_world.txt |
从输出结果中我们可以看到,包含 hello 的行有第 3 行和 第 12 行。
2.5 -A 和 -B 参数
-A 里面的 A 表示 After,-B 里面的 B 表示 Before。两个参数后面需要跟一个数字,表示我现在不仅要输出满足 <搜索字符串> 的那行,我还要将其前面和后面多少行也输出。
举个例子容易理解一些:
1 | grep -n -A 2 -B 3 'hello' hello_world.txt |
上面的命令是说:我现在不仅输出包含 hello 的行,我还要将其前面(-B 参数)的 3 行、其后面的(-A 参数)的 3 行输出来。
2.6 -r 参数
Linux 里面很多命令后面的 -r 参数大多表示递归的意思,grep 也是。
grep 后面加上 -r 参数,表示要搜索一个目录下面的所有文件(包括子目录里面的文件)是否包含 <搜索字符串> 。
看下面的例子:
1 | grep -r -i 'cnnmnist' . |
输出:
1 | user@DataServer:/datapool/workspace/tanjuntao/FL-Influence$ grep -r -i 'cnnmnist' . |
可以看到,当前目录(包含子目录里面的文件)中包含 cnnmnist 字符串的文件均被检索出来了。
2.7 <搜索字符串> 为正则表达式
grep 最强大的功能还是配合正则表达式一起使用,这篇文章不准备详细介绍,后面会单独写一篇介绍 bash shell 里面正则表达式的使用方法,以及如何配合 grep 、awk 等文本处理程序一起使用。
3. References
《鸟哥的 Linux 私房菜》10.6.1 节 & 11.2.2 节