grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

grep家族里包括grep(使用基本正则表达式),egrep(可使用扩展正则表达式),fgrep(不支持使用正则表达式)

grep的用法为:

   grep [OPTION]... PATTERN [FILE]...

        常用选项:

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

        -i:忽略字符大小写;

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

        -v, --invert-match:反向匹配;

        -E:支持扩展的正则表达式(相当于egrep);

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

例如:要查找/etc/passwd文件中"root"就可以这样写: 

[root@localhost ~]# grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin


但是这样凡是包含了root的字符都出来了,如果想要精确查找的话就要使用一个大杀器---正则表达式了。

正则表达式:使用单个字符串来描述、匹配一系列符合某个句法规则的字符串在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

那么,最基本的正则表达式元字符有哪些呢?

字符匹配:

     .:匹配任意单个字符

 wKiom1bjojzjwM3RAABROptGE_I873.png

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

wKiom1bjon-y1JMFAABmSIsjYMI613.png

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

        表示在范围内的反而不匹配了,查找的都是不属于该范围的内容。

    [:digit:]等同与[0-9]:表示数字

    [:lower:]等同于[a-z]:表示小写字母

    [:upper:]等同与[A-Z]:表示大写字母

    [:alpha:]表示所有的字母(包括大写和小写)

    [:alnum:]:表示所有的数字和字母

    [:space:]:表示空格

    [:blank:]:空白和Tab键等

    [:punct:]:表示特殊字符 

wKioL1bjo0Owx6q8AABbFYHlyNg168.png

次数匹配:用在要指定其出现的次数的字符后面,用限制其前面的字符要出现的次数;默认工作于贪婪模式;

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

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

wKiom1bjovzDeTNpAABndEK3xGQ440.png


   \+:匹配前面的字符至少1次;

 wKioL1bjo8CCAXN3AABgnKUSr-s853.png

                        

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

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

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

       \{0,n\}:至多n次;

       \{m,\}:至少m次;

 wKioL1bjo9SyRVCEAABDcLuSCU0159.png

 

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

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

 wKiom1bjo3Pj481FAAAcORBQ-ws768.png

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

 wKiom1bjo4Oh3R_3AABQ9yNWfCE112.png

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

   ^$:空行

   ^[[:space:]]*$:空行

 wKiom1bjo5igRT78AAATadIEa8M314.png

 

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

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

 wKioL1bjpC-hn9yRAABer7LRSWo870.png

 

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

wKioL1bjpD-hqT9XAAAfq_rBSMA983.png

   \<PATTERN\>:单词锚定

 wKioL1bjpD-xOpXuAAAly63c3H4083.png



分组与引用

    

    分组

    \(PATTERN\)将此模式匹配到的结果当作一个整体进行处理;并且匹配到的结果会记录于正则表达式内部变量中


    后向引用:引用前面的括号中的模式所匹配到的结果。引用方式为\1,\2...

例如:显示在文本中有l..e,并且后面有以此单词加r的:

wKioL1bjqHXwfIFLAABOTFif-XA293.png


egrep:

    egrep与grep最大的不同是egrep支持扩展正则表达式,并且在写法上也不需要加"\"来转义。

    

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

    字符匹配:

       .:任意单个字符

wKiom1bjuRTRAcvUAAAVAVPxUG0732.png


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

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

wKioL1bjuZvifbrJAAAagv7bryk135.png


匹配次

       *:任意次;

       ?:0次或1次;

       +:1次或多次;

       {m}:匹配m次;

       {m,n}:至少m次,至多n次;

       {0,n}

       {m,}

wKioL1bjuZvTzdXkAAAaSGzVzKA855.png

 位置锚定:

        ^:行首

        $:行尾

        \<, \b:词首

        \>, \b:词尾


匹配以m开头,e结尾的行

wKiom1bjuRXTWA-WAAATU321Eho568.png



注意,词首或词尾锚定的时候还要”\”

wKiom1bjuRXgQZwZAAAYs9m2Hyc377.png


    分组及引用:

        分组(pattern),括号中的模式匹配到的字符会被记录于正则表达式引擎内部的变量中;

        后向引用:\1, \2, ...

wKioL1bjuZzAWyo5AAAcXB4ycnQ158.png

     或者:

       a|b:a或者b

       C|cat:表示C或cat

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

wKiom1bjuRbw6FXqAAAwHuc1e98177.png



综合练习:

    1、显示/etc/passwd文件中不以bash结尾的行; 

     [root@localhost ~]# grep -v "bash$" /etc/passwd
     [root@localhost ~]# egrep -v "bash$" /etc/passwd

   

 2、找出/etc/passwd文件中的三位或四位数;  

    [root@localhost ~]# grep "\<[0-9]\{3,4\}\>" /etc/passwd    
    [root@localhost ~]# egrep "\<[0-9]{3,4}\>" /etc/passwd

   

 3、找出/etc/grub2.cfg文件中,以至少一个空白字符开头,后面又跟了非空白字符的行;

    [root@localhost ~]# grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
    [root@localhost ~]# egrep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg

     

4、找出"netstat  -tan”命令的结果中,以‘LISTEN’后跟0或多个空白字符结尾的行;   

    [root@localhost ~]# netstat -tan | grep "LISTEN[[:space:]]*$"
    [root@localhost ~]# netstat -tan | egrep "LISTEN[[:space:]]*$"

    

 5、找出"fdisk  -l“命令的结果中,包含以/dev/后跟sd或hd及一个小字母的行;   

    [root@localhost ~]# fdisk -l | grep "/dev/[sh]d[a-z]\>"
    [root@localhost ~]# fdisk -l | grep "/dev/[sh]d[a-z]\>"

   

  6、找出”ldd  /usr/bin/cat“命令的结果里文件路径;

    [root@localhost ~]# ldd /usr/bin/cat | grep -o "/[^[:space:]]\+"
    [root@localhost ~]# ldd /usr/bin/cat | egrep -o "/[^[:space:]]+"


 7、找出/proc/meminfo文件中,所有以大写或小写s开头的行;至少用三种方式实现;

    [root@localhost ~]# egrep "^(s|S)" /tmp/meminfo
    [root@localhost ~]# grep "^[sS]" /tmp/meminfo
    [root@localhost ~]# grep -i "^s" /tmp/meminfo

  

  8、显示当前系统上root、centos或slackware用户的相关信息;

    [root@localhost ~]# egrep "^(root|centos|slackware)\>" /etc/passwd


   9、echo输出一个绝对路径,使用egrep取出其基名;                   

    [root@localhost ~]# echo /etc/passwd/ | egrep -o "[^/]+/?$"


  10、找出ifconfig命令结果中的1-255之间的整数;

    [root@localhost ~]# ifconfig | egrep "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"

      

 11、添加用户bash、testbash、basher及nologin,要求前三个用户的默认shell为/bin/bash,nologin的默认shell为/sbin/nologin,而后找出其用户名与shell名相同的用户;

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