Linux文本搜索命令grep
grep
是一款非常强大的命令行工具,与 sed
、awk
号称 Linux 三剑客。它的主要作用是使用 表达式 在文本文件中进行搜索查找,并将匹配到的 行 打印出来。
grep
命令的全称是 Global Regular Expression Print
,支持 正则表达式,在较大的文本文件进行搜索时非常有用。
语法说明
grep
命令语法如下
1 | grep [OPTION...] PATTERNS [FILE...] |
在使用命令时,需要指定两个参数:
PATTERNS
:用于搜索的表达式,可以使用正则表达式FILE
:要搜索的文本文件,*…* 表示可以指定多个文件,同时对多个文件进行搜索
还可以通过 OPTION
选项,指定更多的搜索条件。需要注意的是,grep
命令是对大小写敏感的。
选项示例
接下来会介绍一些 grep
命令常用搜索方式和选项
1. 最简单的文件搜索
搜索 foo.txt 文件中包含 hello
的行,并打印出来
1 | grep hello foo.txt |
如果要搜索的表达式包含多个单词,或者是表达式包含空格,可以将表达式外边加引号
1 | grep "linux ubuntu" foo.txt |
2. 搜索多个文件
在命令行中可以指定多个文件进行搜索,在表达式后边可以指定多个文件,多个文件用 空格 隔开
1 | grep "hello" foo.txt bar.txt |
3. 忽略大小写
默认情况下 grep
是大小写敏感的,有时候我们不希望区分大小写,可以指定 -i
选项
1 | grep "hello" foo.txt |
如果 foo.txt 中包含 Hello
也是可以搜索到并打印出来的
4. 精确搜索整个单词
有时候我们希望搜索完整的单词,而不是单词的一部分,比如下边的示例,只有 computer
才可以匹配的到
1 | $ grep -w "computer" foo.txt |
5. 搜索匹配行的个数
如果只想知道匹配了多少行,而不打印每行的内容,可以指定 -c
选项
1 | grep -c "hello" foo.txt |
6. 反向搜索
有一个配置文件,不想显示注释掉的配置项,则可以通过 -v
来排除注释掉的内容
1 | grep -v "^#" nginx.conf |
上述指令,会排除掉所有以 #
开头的配置项
7. 显示行号
有时候我们需要显示匹配行所在的行号,可以使用 -n
选项
1 | $ grep -n "hello" foo.txt |
8. 只显示匹配的内容,而不是行
grep
默认会把匹配到的整行内容打印出来,有时希望只打印匹配的内容,而不是整行的内容,可以通过 -o
选项来完成
1 |
|
9. 搜索目录所有文件
如果想搜索匹配目录中所有文件,非常简单,使用通配符 *
即可
1 | grep "init_worker" *.lua |
有时目录中还会包含多级的目录和文件,我们要搜索匹配目录中所有的文件,可以指定选项 -r
来递归搜索匹配所有的文件
1 | $ grep -r "init_worker" *.lua |
其实这个用法非常有用,我们经常会遇到在命令行下搜索代码中函数调用或变量哪些地方使用,使用上述命令就可以完成,也很高效。
10. 只显示匹配到的文件
如果我们只想显示匹配到的文件名称,而不打印具体的匹配的行内容,一般是在递归搜索时比较管用
1 | grep -l -r "init_worker" *.lua |
11. 最多只匹配多少行
如果我们只想打印匹配到的前 3 行,使用 -m 3
选项,在匹配 3 行后就停止读文件
1 | grep -m3 "sys" foo.txt |
12. 除匹配行外,额外打印N行
-A N
:除了匹配行,再额外打印下边 N 行-B N
:除了匹配行,再额外打印上边 N 行-C N
:除了匹配行,再额外打印上边 N 行,下边 N 行
13. 指定多个匹配条件
1 | $ grep -e hello -e world foo.txt |
从输出内容可以看出,两个 -e
指定的表达式是 或 的关系,而不是 与 的关系
grep
命令选项是非常重要的,它为我们提供了非常丰富的使用方式,我们可以使用各种命令行选项来完成大文件的搜索匹配。
正则示例
grep
强大的搜索匹配能力,除了支持丰富的选项外,还因为它能够支持正则匹配。
正则表达式虽然并不很复杂,但其非常灵活,表达能力非常强大,这篇文章只是为了介绍 grep
命令的使用,所以不会特别地详细介绍,只会介绍一些经典的用法。
1. 以开头匹配
前边介绍的例子中,只要文件中有匹配表达式的都会被打印出来。如果我们只需要匹配以行开头的内容呢?可以使用 ^
符号表示 以行开头
1 | $ grep "^hello" foo.txt |
可以看到只有以 hello 开头的行才可以被匹配并打印出来。
2. 以结尾匹配
类似的,如果只想搜索匹配以行结尾的内容,可以按照如下的方式来执行命令
1 | $ grep "hello$" foo.txt |
$
表示以行结尾,所以上边的命令只会匹配 hello
结尾的行
3. 匹配空行
如果我们想匹配空行,可以通过 ^$
实现。因为在开头和结尾之间没有任何内容,就可以理解为空行了
1 | grep -v "^$" foo.txt |
上边的命令,就是不显示空行的内容
4. 多条件匹配
如果我们想指定多个匹配条件,可以使用正则表达式来实现
1 | grep -E "hello|world" foo.txt |
上述命令表示包含 hello
或 world
的行会被匹配并打印出来。需要注意的是,grep
默认只支持一般正则,|
属于扩展正则,需要指定 -E
选项。
1 | # 上述命令等效于 |
5. 多条件同时匹配
上边的例子,其实是指定了 2 个条件,只要匹配其中一个就会被打印出来。有时我们需要同时匹配多个条件,只有多个条件同时满足才算匹配,其实就是 与 的关系。
1 | $ grep -P '^(?=.*you)(?=.*me)' test.log |
可以看到,只有同时包含 you
和 me
的行才能被打印出来。需要注意的是,这里指定了 -P
选项,表示使用了 Perl 正则表达式。
好了,表达式的示例就先列举这么多,想要把 grep
命令用的好,就需要熟悉正则表达式了。
简单总结
上边介绍一些典型的示例操作,相信大家应该已经初步了解了 grep
的用法。下面我把常用的选项的含义再总结出来,希望对你有用。
-A
:除了匹配到的行,额外显示下边的 N 行-B
:除了匹配到的行,额外现实上边的 N 行-C
:除了匹配到的行,额外显示上边和下边的 N 行-c
:统计匹配的行数-e
:指定多个表达式,实现多个选项间 或 的关系-E
:支持扩展的正则表达式-F
:相当于 fgrep 命令-i
:忽略大小写-n
:显示匹配的行号-o
:仅显示匹配到的字符串内容-q
:安静模式,不打印匹配到的内容行,一般脚本中通过返回值来判断是否有匹配-s
:忽略错误信息的显示-v
:反向搜索,也就是显示没有被匹配到的行-w
:匹配完整的单词,而不是不分的字符串-P
:支持 Perl 正则-m
:指定最大只匹配的 N 行--color
:将匹配到的内容以突出的颜色显示出来