grep家族乃Linux系统中文本处理的三剑客之一,包括:grep、egrep、fgrep三位成员,是对系统内大量复杂文本搜索很好的使用工具,主要是基于“PATTRE”对给定的文本进行搜索操作。

   其中grep和egrep支持使用正则表达式,根据用户指定的“PATTER”(过滤条件)对目标文本逐行进行匹配检查。

   正则表达式,则是由一类特殊字符及文本字符所编写的模式,其有些字符不表示其字面意义,而是用于表示控制或通配的功能。可分为两类:基本的正则表达式(BRE)和扩展的正则表达式(ERE)

   其中grep支持基本的正则表达式,egrp支持扩展的正则表达式。下面将会对grep和egrp及相应正则表达式和用法做详细说明。

   一、grep和基本的正则表达式:

    grep命令:

       基本格式:

        grep [OPTIONS] PATTERN [FILE...]

       常用选项:      

        --colsr=auto:对匹配到的文本着色后高亮显示;

         CentOS7环境下系统默认对此做了设定:        

         [root@localhost ~]# alias

         alias cp='cp -i'

         alias egrep='egrep --color=auto'

         alias fgrep='fgrep --color=auto'

         alias grep='grep --color=auto'

         即输入“grep”命令,默认为“grep --color=auto”命令。

        -i:忽略字符大小写;       

         [root@localhost ~]# grep -i mgedu /etc/passwd

         mgedu:x:1001:1001::/home/mgedu:/bin/bash

         Mgedu:x:1002:1002::/home/Mgedu:/bin/bash

         [root@localhost ~]# 

          不区分大小写,“mgedu”和“Mgedu”都匹配。

         -o:仅显示匹配到的文本自身;

         [root@localhost ~]# grep -i mgedu /etc/passwd

         mgedu:x:1001:1001::/home/mgedu:/bin/bash

         Mgedu:x:1002:1002::/home/Mgedu:/bin/bash

         [root@localhost ~]# grep -i -o mgedu /etc/passwd

         mgedu

         mgedu

         Mgedu

         Mgedu

         [root@localhost ~]#

         忽略大小写且仅显示“medu”和“Mgedu”所匹配文本自身,不显示其它内容。 

         -v,--invert-match:反向匹配;即显示没匹配模式的行。

            [root@localhost tmp]# cat test

               Good,better,best.

               Never let is rest.

               Till good is better.

               And better is best.

            [root@localhost tmp]# grep -i good test

               Good,better,best.

               Till good is better.

            [root@localhost tmp]# grep -i -v good test

               Never let is rest.

               And better is best. 不再显示有“good”的行。

            [root@localhost tmp]#

          反向匹配显示了不包含包含“good”或“Good”的所有内容。 

         -q,--quiet,--sillent:静默模式,不输出任何信息;

         以节约系统资源,不再列举。

        -e PATTREN:同时指定多个正则表达式模式,多模式使用机制;

            [root@localhost tmp]# grep -e mgedu -e Mgedu -e gyjz /etc/passwd

            gyjz:x:1000:1000:gyjz:/home/gyjz:/bin/bash

            mgedu:x:1001:1001::/home/mgedu:/bin/bash

            Mgedu:x:1002:1002::/home/Mgedu:/bin/bash

            [root@localhost tmp]#

         同进指定“mgedu、Mgedu、gyjz”三个模式,并显示。

        -f FILE:FILE为每行包含了一个模式的文本文件,即grep script      

          [root@localhost tmp]# cat test.1

          ^[m|M].*bash$

          [root@localhost tmp]# grep -f test.1 /etc/passwd

          mgedu:x:1001:1001::/home/mgedu:/bin/bash

          Mgedu:x:1002:1002::/home/Mgedu:/bin/bash

          [root@localhost tmp]#

         显示了匹配“test.1”文件模式的内容。

        -E:支持使用扩展正则表达式;相当于egrep,不再详述。

        -F:支持使用固定字符串,不支持正则表达式,相当于fgrep,不再详述。

           匹配内容上下文:

        -A NUM:显示匹配结果后几行

        -B NUM:显示匹配结果前几行

        -C NUM:显示匹配结果前后几行

          [root@localhost tmp]# cat test

            Good,better,best.

            Never let is rest.

            Till good is better.

            And better is best.

          [root@localhost tmp]# grep -A 1 Good test

            Good,better,best.

            Never let is rest.  显示后一行

         [root@localhost tmp]# grep -B 1 best test

            Good,better,best.  为第一行,前一行无内容。

          --

            Till good is better.  显示前一行

            And better is best.

          [root@localhost tmp]# grep -C 1 rest test

            Good,better,best.

            Never let is rest.  前后1行都显示。

            Till good is better.

         [root@localhost tmp]# 


    基本正则表达式元字符:


      字符匹配:

         .:匹配任意单个字符;

         [root@localhost tmp]# grep ".gedu" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         点号匹配单个字符,文件中“m”或“M”满足匹配条件。 

         []:匹配范围内任意单个字符;

         [root@localhost tmp]# grep "[mM]gedu" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         “[]”内的“m”或“M”都匹配。 

         [^]:匹配范围外任意单个字符;       

         [root@localhost tmp]# grep [^[:lower:]]gedu  /etc/passwd

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         “[^[:lower:]]”表示,不包含小写字母,“Mgedu”匹配。

         [:lower:]表示所有小写字母,其它常用特殊字符有:

           [:diglt:]任意数字,[:alpha:]任意字母,[:upper:]任意大写字母,

         [:space:]任意空白字符,[:alnum:]任意数字和字母,[:blank:]任意空格,                [:punct:]任意标点符号,[:cntrl:]任意控制符等。


      匹配次数:

       用在要指定其出现的次数的字符后面,用于限制其前面的字符要出现的次数;

     默认工作于贪婪模式;

    *:匹配前面的字符任意次(0,1或多次);

         [root@localhost tmp]# cat test.2

         xy

         xay

         xxaby

         xxxyabc

         yabc

         aybc

         [root@localhost tmp]# grep "x*y" test.2

         xy

         xay

         xxaby

         xxxyabc

         yabc

         aybc

         [root@localhost tmp]#

         "x*y"表示y前的x出现任意次数,即x出现0次或多次,所有test.2中内容都匹配; 

.*:任意长度的任意字符;

          前面讲过“.”表示任意单个字符,“*”表示前面字符任意次。

          所有“.*”则表示任意字符。

         [root@localhost tmp]# grep "M.*" /etc/passwd

         systemd-network:x:998:997:systemd Network Management:/:/sbin/nologin

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         "M.*"表示M后跟任意字符。 

\+:匹配前面的字符至少一次(一次或多次);

          test.2文件内容同上,此处不再显示。

         [root@localhost tmp]# grep "x\+y" test.2

         xy

         xxxyabc

         [root@localhost tmp]#

         "x\+y"表示y前x出现一次或多次,xy,xxxyabc匹配,y前没有x的不匹配。

          xay,虽y前有1个x,但中间有a,不匹配。

\?:匹配前面的0次或1次,即前面的字符可有可无;

         [root@localhost tmp]# grep "x\?y" test.2

         xy

         xay

         xxaby

         xxxyabc

         yabc

         aybc

         [root@localhost tmp]# 

         "x\?y"表示y前x出现0次或1次,即y前有无x均可。所有test.2中内容都匹配。

\{m\}:其前面的字符出现m次,m为非负整数;        

         [root@localhost tmp]# grep "x\{2\}y" test.2

         xxxyabc

         [root@localhost tmp]#

         "x\{2\}y"表示y前x出现2次,xxxyabc匹配。 

\{m,n\}:其前面的字符出现m到n次,m,n为非负整数;

  \{m,\}至少m次,\{0.n\}最多n次

         [root@localhost tmp]# grep "x\{1,3\}y" test.2

         xy

         xxxyabc

         [root@localhost tmp]#

         "x\{1,3\}y"表示y前x出现1-3次,xy,xxxyabc匹配。


 

      位置锚定:

    限制使用模式搜索文本时,限制模式所匹配到的文本只能出现于目标文本的哪个位置;

    ^:行首锚定;用于模式的最左侧,^PATTERN

         [root@localhost tmp]# grep "^Mgedu" /etc/passwd

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         "^Mgedu"表示以Mgedu开头的行。 

$:行尾锚定;用于模式的最右侧,PATTERN$

         [root@localhost tmp]# grep "tcsh$" /etc/passwd

         fedora:x:5001:5001:Fedora Core:/home/fedora:/bin/tcsh

         [root@localhost tmp]#

         "tcsh$"表示以tcsh结尾的行。 

  ^PATTERN$:要让PATTERN完全匹配一整行;

   ^$:空行;


      单词匹配:

        由非特殊字符组成的连续字符(字符串)都称为单词;

\<或\b:词首锚定,用于单词模式的左侧,格式为\<PATTERN       

         [root@localhost tmp]# grep -i "\<Mg" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]# 

         "\<Mg"表示以Mg开头的单词,-i,不区分大小写。

\>或\b:词尾锚定,用于单词模式的右侧,格式为PATTERN\>

    \< PATTERN \>:锚定单个单词;

         [root@localhost tmp]# grep  "edu\>" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]# 

         "edu\>"表示以edu结尾的单词。


      分组与引用:

\(PATTERN):将此PATTERN匹配到的字符当作一个不可分隔的整体进行处理;

       注意:分组括号中的模式匹配到的字符会被正则表达式引擎自动记录于

        内部的变量中,这些变量是\1,\2,...

\n:模式中第n个左括号以及与之匹配的右括号之间的模式所匹配到的字符串;

           (不是模式,而是模式匹配的结果)

\1:第一组括号中的PATTERN匹配到的字符串;

          \2:第二组括号中的PATTERN匹配到的字符串;

         ……以此类推

   满足后向引用机制:引用前面的括号中的模式所匹配到的字符串;

         例如:添加用户bash,testbash,basher及nologin,

 要求前三个用户的默认shell为/bin/bash,noloign的shell为/sbin/nologin,

 而后找出其用户名与shell相同的用户;

  用户创建过程不再详述,直接查看结果。

         [root@localhost tmp]# grep "^\([a-z0-9]\+\)\>.*\1$" /etc/passwd

         sync:x:5:0:sync:/sbin:/bin/sync

         shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

         halt:x:7:0:halt:/sbin:/sbin/halt

         bash:x:5006:5006::/home/bash:/bin/bash

         nologin:x:5009:5009::/home/nologin:/sbin/nologin

         [root@localhost tmp]#

         注意:在基本正则表达式中“()”需要用“\”进行转意

             在扩展正则表达式中无需转意。


   二、egrep和扩展的正则表达:

    egrep命令:

       基本格式:

        egrep [OPTIONS] PATTERN [FILE...]

       常用选项:

        同grep常用选项类似,不再详述。

    

    扩展正则表达式的元字符:

    

       字符匹配:

.:匹配任意单个字符;

[]:匹配范围内的任意单个字符;

[^]:匹配范围外的任意单个字符;

         [root@localhost tmp]# egrep "[mM]gedu" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]# 

        与基本正则表达式无区别,其用法同基本正则表达式,不再过多详述。


      匹配次数:

*:匹配前面的字符任意次(0,1或多次);

?:匹配前面的字符0次或1次,即前面的字符可有可无;

+:匹配前面的字符1次或多次;

    {m}:其前面的字符出现m次,m为非负整数;

{m,n}:其前面的字符出现至少m次,最多n次,m,m为非负整数;

  {m,}至少m次,{0.n}最多n次

        与基本正则表达式区别:无需使用“\”转意符转意。

         [root@localhost tmp]# cat test.2

         xy

         xay

         xxaby

         xxxyabc

         yabc

         aybc

         [root@localhost tmp]# egrep "x{1,3}y" test.2

         xy

         xxxyabc

         [root@localhost tmp]#

        其用法同基本正则表达式,不再过多详述。


      位置锚定:

    ^:行首锚定;用于模式的最左侧,^PATTERN

$:行尾锚定;用于模式的最右侧,PATTERN$

         [root@localhost tmp]# egrep "tcsh$" /etc/passwd

         fedora:x:5001:5001:Fedora Core:/home/fedora:/bin/tcsh

         [root@localhost tmp]# 

         与基本正则表达式无区别,其用法同基本正则表达式,不再过多详述。


      单词锚定匹配:

\<或\b:词首锚定,用于单词模式的左侧,格式为\<PATTERN,\b

\>或\b:词尾锚定,用于单词模式的左侧,格式为\>PATTERN,\b

   \< PATTERN \>:锚定单个单词;

         [root@localhost tmp]# egrep -i "\<mgedu\>" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]# 

         与基本正则表达式无区别,其用法同基本正则表达式,不再过多详述。


      分组及引用:     

        (PATTERN):将此PATTERN匹配到的字符当作一个不可分隔的整体进行处理;

       注意:分组括号中的模式匹配到的字符会被正则表达式引擎自动记录于

        内部的变量中,这些变量是\1,\2,...

 \n:模式中第n个左括号以及与之匹配的右括号之间的模式所匹配到的字符串;

           (不是模式,而是模式匹配的结果)

 \1:第一组括号中的PATTERN匹配到的字符串;

            \2:第二组括号中的PATTERN匹配到的字符串;

            ……以此类推

   满足后向引用机制:引用前面的括号中的模式所匹配到的字符串;

        与基本正则表达式区别:“()”在基本正则表达式中需要用“\”转意符进行转意,

                    在扩展正则表达式中,无需用“\”转意符转意。

        其用法同基本正则表达式,不再过多详述。


      或者:

        整个左侧内容与整个右侧内容做或运算

  a|b:a或者b

  注意:C|cat:表示C或cat;(C|c)at:表示Cat或cat;

         [root@localhost tmp]# egrep "^[M|m]gedu+\>" /etc/passwd

         mgedu:x:5004:5004::/home/mgedu:/bin/bash

         Mgedu:x:5005:5005::/home/Mgedu:/bin/bash

         [root@localhost tmp]#

         "^[M|m]gedu+\>"表示以“Mgedu”或“mgedu”单词为首的行。


   三、总结

    1、egrep = grep -E

    2、grep命令是基于基本的正则表达式,egrep命令是基于扩展的正则表达式;

    3、在匹配次数的应用中,除“*”外的其它符号,在基本的正则表达式中需要用

      “\”转意符转意,在扩展的正则表达式中无需转意;

    4、在分组引用的应用中,“()”在基本的正则表达式中需要用“\”转意符转意,

      在扩展的正则表达式中无需转意;

    5、在扩展的正则表达式中有“或者”的应用,在基本的正则表达式中无此应用;


   以上便是个人对grep、egrep和正则表达式的一些详述与总结,希望对Linux学习都有所帮助。