这篇文章总结下 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 节