# grep命令详解

- 30

- A+

所属分类：Linux基础 常用命令

如果你是一个新手，请从头阅读这篇文章，如果你只是忘记了grep命令的一些常用选项，直接查看文章尾部的总结部分即可。

先说说grep命令能做什么？

我们可以使用grep命令在文本中查找指定的字符串，就像你在windows中打开txt文件，使用快捷键 "Ctrl+F" 在文本中查找某个字符串一样，说白了，可以把grep理解成字符查找工具。

grep是Linux中最常用的"文本处理工具"之一，grep与sed、awk合称为Linux中的三剑客。

grep的全称为： Global search Regular Expression and Print out the line

全称中的"Global search"为全局搜索之意。

全称中的"Regular Expression"表示正则表达式。

所以，从grep的全称中可以了解到，grep是一个可以利用"正则表达式"进行"全局搜索"的工具，grep会在文本文件中按照指定的正则进行全局搜索，并将搜索出的行打印出来。

当然，不使用正则表达式时也可以使用grep，但是当grep与正则表达式结合在一起时，威力更强大。

我们先来看一个最简单的使用示例，从最简单的示例开始认识grep。

为了实验方便，我们先准备一个测试文件，文件名为testgrep，文件内容如下。

假设，现在我们想要从testgrep文本文件中搜索包含"test"字符串的行，则可以使用如下命令

上图中的命令表示使用grep命令，在testgrep文件中搜索包含"test"字符串的行，并将包含test字符串的行打印出来。

于是，testgrep文件中的第一行被打印了出来，默认情况下，grep是区分大小写的，所以，文件中包含大写"TEST"的行没有被打印出来。

grep的使用是不是很简单，我们继续聊。

如果我们想要在搜索字符串的时候，不区分大小写，应该怎样做呢？grep很贴心，为我们准备了一个选项，使用"-i"选项，即可在搜索时不区分大小写，示例如下：

如上图所示，在不区分大小写的情况下，由于testgrep文本中的第一行与第五行中都包含"test"，所以，这两行都被打印了出来。

由于testgrep文本中的内容不较少、行比较少，所以，我们能数过来，是第一行与第五行包含"test"字符，如果文本中有1000行，我们还想要知道哪行文本包含"test"字符串，则可以使用"-n"选项，表示显示打印出的行在文本中的行号，示例如下。

如上图所示，grep不仅将符合条件的行输出了，同时还显示了行号，证明testgrep文本中的第1行与第5行，在不区分大小写的情况下，都包含字符串"test"。

在centos6中，我们使用grep在文本中搜索出的行虽然会被打印了出来，但是在打印这些行时，被匹配到的关键字没有高亮显示，如果我们想要高亮显示行中的关键字，该怎么办呢？我们可以使用"--color"选项，高亮显示行中的关键字，示例如下

注:"--color选项"是长选项

使用"--color"与使用"--color=auto"的效果相同，都表示高亮显示关键字，我比较懒，习惯使用"--color"。

在centos7中，系统默认为grep命令配置了别名，所以在centos7中使用grep命令时，不用显式的指定"--color"选项，默认就会高亮显示被匹配到的关键字，在centos7中使用alias命令，即可查看到grep命令的别名，如下

可以看到，centos7中为grep命令配置的别名中，默认包含了--color选项，所以，不用显示指定，也可高亮显示。

所以，我们也可以在centos6中借鉴这种方法。

上图中，testgrep文本中一共有两行包含"test"字符串，如果我们只想知道有多少行包含指定的字符串，而不在乎哪些行包含这些字符串，我们可以使用如下命令，获取到符合条件的总行数。

没错，使用"-c"选项即可只统计符合条件的总行数，而不会打印出行。

之前的示例中，包含关键词的行都会被打印出来，整行都会被打印出来，如果我们只想看被匹配到的关键字，不想整行都被打印出来，可以吗？必须的，使用"-o"选项即可只打印出匹配到的关机字，而不打印出整行，示例如下。

如上图所示，使用"-o"选项，可以只显示被匹配到的关键字，而不是讲整行的内容都输出。

但是需要注意，"-o"选项会把每个匹配到的关键字都单独显示在一行中进行输出，什么意思呢？看如下示例即可明白。

如上图所示，当没有使用"-o"选项时，包含"123"字符串的行都会被打印出来，当同一行中包含多个"123"时，所在行会被打印出来，对应的关键字也会高亮显示，当使用了"-o"选项时，每个被匹配到的关键字都会被单独打印在一行中，如上图所示，第三个"123"与第四个"123"都属于第10行的文本，但是它们仍然各自独占一行的输出了。

其实，我们在使用grep命令搜索文本时，往往有这种需求：在找到对应的关键字时，同时需要显示关键字附近的信息，什么意思呢？

我们来看一个场景，就能明白，我们新建了一个测试文件：testgrep1，测试文件内容如下

假设，我们想从testgrep1文件中找出"年龄为18"的人，我们该怎么找呢？你可能会尝试使用如下命令。

如上图所示，我们是匹配到了"年龄：18"的行，但是我们并不能从结果中得知年龄为18的人的姓名，因为姓名与年龄并不在一行中，那么我们该怎么办呢？

我们可以使用"-B"选项，显示符合条件的行之前的行，"B"有before之意，示例如下

如上图所示，包含字符串"年龄：18"的行被高亮输出了，同时，符合条件的行"之前的一行"也被打印了出来，这时，我们就能从结果中得知，朱双印今年18岁，王尼美今年18岁。

没错，上例中的"-B1"选项表示显示符合条件的行的同时还显示之前的1行，举一反三，"-B5"代表同时显示之前的5行，"-B3"代表同时显示之前的3行，"-B"选项的后面必须有数字，否则会报错。

与"-B"选项对应的选项是"-A"选项，"-B"有Before之意，"-A"有After之意，聪明如你，一定已经猜到了"-A"的含义，没错，"-A"代表显示符合条件的行的同时，还要显示之后的行，"-A3"表示同时显示符合条件的行之后的3行，我就不再赘述了。

说了"-A"，说了"-B"，现在说说"-C"，"-C"选项可以理解为"-A与-B"的结合，"-C"选项表示在显示符合条件的行的同时，也会显示其前后的行，如"-C1"，"-C1"表示打印符合条件的行的同时，也打印出之前的一行与之后的一行，"-C"有Context之意（上下文之意），示例如下。

这样我们就能看到"年龄是18岁"的人的所有信息了。

有的时候，我们往往需要进行所谓的"精确匹配"，但是使用之前的方法似乎无法满足我们，示例如下。

上图中，当我们在文本中搜索"zsy"字符串的时候，"zsy"、"zsythink"、"123zsy123"所在的行都被匹配到了，因为"zsythink"中也包含了"zsy"，所以也被匹配到了，但是当我们想要"精确匹配"zsy字符串的时候，按照上例中的方法就无法做到了，所谓的精确匹配，就是"zsy"作为一个独立的单词存在，而不是包含于某个字符串中，那么，如果有这种需求，我们怎么办呢？使用"-w"选项可以实现我们的需求，示例如下。

如上图所示，只有"zsy"作为一个独立的单词存在的时候，才会被匹配到，"zsy"包含于某个字符串的时候，则不会被匹配到，这就是所谓的精确匹配，"-w"有word之意，表示搜索的字符串作为一个独立的单词时才会被匹配到。

有的时候，我们需要反向查找，比如，查找"不包含某个字符串"的行，这个时候，我们需要用到"-v"选项，示例如下。

上例表示查找出文本中不包含"zsy"字符串的行。

某些场景下，我们可能想要同时从多个目标中匹配，什么意思呢？看了示例就秒懂，示例如下。

上例中，我们同时在文本中搜索了"abc"字符串与"test"字符串，包含这两个字符串中任意一个的行都会被打印出来，没错，就像上图中的示例一样，使用"-e"选项可以同时匹配多个目标，多个目标之间存在"或"关系，即匹配其中的任意一个都算作匹配成功。

在写脚本时，你可能只是想要利用grep判断文本中是否存在某个字符串，你只关心有没有匹配到，而不关心匹配到的内容，你只关心有，或者没有，这时，我们可以使用grep的静默模式，示例如下。

当使用"-q"选项时，表示grep使用静默模式，静默模式下grep不会输入任何信息，无论是否匹配到指定的字符串，都不会输出任何信息，所以，我们需要配合"echo $?"命令，查看命令的执行状态，如果返回值为0，证明上一条grep命令匹配到了指定的字符串，如果返回值为1，则证明上一条grep命令没有匹配到指定的字符串，就像上图示例中显示的那样，静默模式下，grep没有输出任何信息，当我们在testgrep文本中查找"test"字符串时，可以匹配到结果，当在文本中查找"ttttttttttttt"字符串的时候，没有匹配到结果，所以，我们只关心有没有匹配到指定字符时，可以使用"-q"选项，但是需要配合"echo $?"命令查看执行状态。

注：如果你对正则表达式还不熟悉，可以先跳过下面的示例，本博客中会对"正则表达式"进行详细总结。

正则表达式系列文章直达链接：正则表达式详解

文章开头说了，grep可以利用正则表达式进行搜索，但是之前的举例中，grep都没有使用正则表达式，只是纯粹的去查找一些字符串，这次，我们使用grep命令，配合正则表达式，来查找我们想要的目标。

比如，我们想要查找某个文本中的合法邮箱，示例如下

眼尖的你肯定发现了，上图中的正则表达式为扩展正则表达式，而不是基础正则表达式，所以，在上述命令中，我使用了"-E"选项。

在使用"-E"选项时，grep才支持"扩展正则表达式"，不使用"-E"选项时，grep默认只支持"基本正则表达式"。

不同的开发语言中，正则表达式的规则可能略有不同，我们在使用grep时，可以使用"-P"选项，指明使用perl兼容的正则表达式。

示例如下：

好了，grep的常用选项我们已经总结完毕，剩下需要做的就是不断的练习了。

其实，除了grep命令，其实还有egrep命令，还有fgrep命令（fast grep），它们有各自的特点。

grep：支持基本正则表达式

egrep：支持扩展正则表达式，相当于grep -E

fgrep：不支持正则表达式，只能匹配写死的字符串，但是速度奇快，效率高，fastgrep

## 总结

为了方便以后回顾，将grep的常用选项总结如下

--color=auto 或者 --color：表示对匹配到的文本着色显示

-i：在搜索的时候忽略大小写

-n：显示结果所在行号

-c：统计匹配到的行数，注意，是匹配到的总行数，不是匹配到的次数

-o：只显示符合条件的字符串，但是不整行显示，每个符合条件的字符串单独显示一行

-v：输出不带关键字的行（反向查询，反向匹配）

-w：匹配整个单词，如果是字符串中包含这个单词，则不作匹配

-Ax：在输出的时候包含结果所在行之后的指定行数，这里指之后的x行，A：after

-Bx：在输出的时候包含结果所在行之前的指定行数，这里指之前的x行，B：before

-Cx：在输出的时候包含结果所在行之前和之后的指定行数，这里指之前和之后的x行，C：context

-e：实现多个选项的匹配，逻辑or关系

-q：静默模式，不输出任何信息，当我们只关心有没有匹配到，却不关心匹配到什么内容时，我们可以使用此命令，然后，使用"echo $?"查看是否匹配到，0表示匹配到，1表示没有匹配到。

-P：表示使用兼容perl的正则引擎。

-E：使用扩展正则表达式，而不是基本正则表达式，在使用"-E"选项时，相当于使用egrep。

希望这篇文章能对你有所帮助~~~客官常来捧场哦，么么哒~~~~~

我的微信公众号
关注"实用运维笔记"微信公众号，当博客中有新文章时，可第一时间得知哦~
赞 246
赏
分享

- 常用命令

- 版权声明：本站原创文章，于2017年5月16日08:37:03，由 朱双印 发表，共 4846 字。
- 如需转载，请在文章头部注明出处：grep命令详解 | 朱双印博客

printf命令详解
awk从放弃到入门（1）：awk基础 （通俗易懂，快进来看）
iptables详解（1）：iptables概念
seq命令详解

### 发表评论取消回复

欢迎 pangzi 再次光临！
修改信息

正在提交, 请稍候...
#

昵称*

邮箱*

网址

有回复时邮件通知我

## 目前评论：30 其中：访客 26 博主 4

2. 临江仙 4
   回复 2020年2月2日 下午9:56 沙发

   博主大大 ，我又来了 (*^__^*) 嘻嘻…… 争取天天来

   - 朱双印 Admin
     回复 2020年2月3日 下午8:06 1层

     @临江仙 哈哈，看到了，加油兄弟~

4. gg 0
   回复 2019年12月10日 上午8:59 板凳

   赞

6. 天南第一剑修 0
   回复 2019年12月2日 下午2:19 地板

   非常感谢老哥的精心分享

8. mark 0
   回复 2019年11月19日 下午4:29 4楼

   # 语法：add_executable( 程序名 源代码文件 ）
   add_executable( HelloC++Test HelloC++Test.cpp )
   add_executable( HelloC++2Test HelloC++Test.cpp )
   add_executable( mmT mmT.cpp )

   比如上面是在终端通过「grep “add_executable” 」拿到的字符串：
   1-我想分割拿到「HelloC++Test 」这个怎么做呢？
   2-通过终端输入去过滤拿到「HelloC++Test 」，这个怎么做呢？

   谢谢楼主大佬。

10. 易明 1
    回复 2019年9月20日 上午9:01 5楼

    简明 赞

12. Postale 1
    回复 2019年8月13日 上午10:47 6楼

    博主写的太好了，通俗易懂，期待博主能出个sed专题。

14. windychang 0
    回复 2019年8月12日 下午4:22 7楼

    写的很详细。赞

16. dual 1
    回复 2019年6月27日 上午10:22 8楼

    有时候 想查找下 mysql –help输出的某个参数 比如 -h mysql –help | grep “-h” 这样 好像会把 -h解析 成 grep的参数 ，请教下如何禁止正则解析

    - 朱双印 Admin
      回复 2019年6月28日 上午9:17 1层

      @dual mysql –help | grep “\-h”

18. xxx 1
    回复 2019年5月10日 下午2:22 9楼

    晚上买香，月光下拜访。

20. AntiAs 0
    回复 2019年3月12日 下午6:13 10楼

    真的很细，感谢了。
    有个疑惑，匹配某字段并输出当前行的同时，一并输出第一行怎么处理呢？
    简单来说，就是匹配字段+当前文件的表头。

    - 临江仙 4
      回复 2020年2月2日 下午9:55 1层

      @AntiAs & sed -n ‘1p’ file 取某些行用sed比较方便，我感觉grep更倾向于查找特定的一串字符。

22. 呼啦啦 1
    回复 2018年12月26日 下午4:06 11楼

    写真很着重，棒

24. joyHe 0
    回复 2018年12月8日 下午5:36 12楼

    awk 和 grep 都看了，博主真的写很棒，通俗易懂，能不能把三剑客的 sed 也出个专题呢

    - chouchoufly 1
      回复 2019年1月11日 下午3:34 1层

      @joyHe +1，写得真好，期待sed专题

    - 略微抖动 2
      回复 2019年6月13日 下午4:09 1层

      @joyHe +1 期待 sed

26. 小胖 1
    回复 2018年9月19日 下午4:46 13楼

    习惯打卡

28. hi 1
    回复 2018年7月21日 下午5:23 14楼

    请教下面的命令”_”、”-“，这两个命令什么意思，grep系列的文章都看完了，没看到这两个符号介绍。
    grep -P “[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+” testgrep2.txt

    - t 2
      回复 2018年10月10日 上午6:59 1层

      @hi 额，你确定那不是普通的可视字符？

30. hi 1
    回复 2018年7月21日 下午5:21 15楼

    另外请教”_”、“-“，这两个符号是什么用途？grep系统文章都看完了，没看到这两个符号的介绍。
    grep -P “[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+” testgrep2.txt

32. hi 1
    回复 2018年7月21日 下午5:16 16楼

    写得很好，学到不少，谢谢，不过这个命令中的？表示什么意思，匹配哪个字符呢？（.cn）这里的”.cn”为什么要加括号呢？
    grep -E “^([[:alnum:]]{6,18})@([[:alnum:]]{1,20})\.(com(.cn)?|org|edu|net|mil|gov|info)$” testgrep2.txt

    - 伯乐 0
      回复 2019年3月14日 下午8:13 1层

      @hi ？代表匹配前面的表达式0次或多次 域名 .com 跟 .cn 不可能同时有啊

34. 朱哥小粉丝 3
    回复 2018年4月26日 下午5:41 17楼

    老哥，我又来留言了，写的真好

    - 朱双印 Admin
      回复 2018年4月27日 上午9:08 1层

      @朱哥小粉丝 谢谢兄弟捧场，共勉~~~

36. hello 2
    回复 2017年12月24日 上午3:47 18楼

    很好

38. nobody 1
    回复 2017年10月20日 下午3:13 19楼

    为什么我没加–color也是高亮显示呢?

    - nobody 1
      回复 2017年10月20日 下午3:20 1层

      @nobody 哦哦，原来在centos7中是默认高亮的，刚才没看到文章下面就评论了

40. 失恋的男子 1
    回复 2017年9月6日 下午10:50 20楼

    很详细，谢谢，表情不能输入哦

    - 朱双印 Admin
      回复 2017年9月7日 上午8:35 1层

      @失恋的男子 能让别人省力的看懂是文章价值的体现，一起加油~~~

- 文章目录

×
×
拖拽到此处
图片将完成下载