Linux文本三剑客之grep族以及相应的正则表达式

 

Grep族是什么?

Grep族是linux学习中搜索文本的重要工具,它基于使用正则表达式来快速简洁的搜索你想要查看的文本。是搜索文本的不二之选

什么时候及在哪里使用grep呢?

上面咱们说到了,grep是文本搜索工具,所以当我们要搜索文本,有搜索文本的需要时我们就可以是使用grep工具。

 

下面我们来谈谈如何使用grep族命令以及涉及到的正则表达式的内容

 

文本搜索工具:grep族:grep, egrep, fgrep 

 

Linux上文本处理三剑客

    grep, egrep, fgrep:文本搜索工具;基于”pattern“对给定文本进行搜索操作;

    sed:Stream EDitor,流编辑器,行编辑工具;文本编辑工具;

    awk:GNU awk,文本格式化工具;文本报告生成器;

 egrepfgrep的命令只跟grep有很小不同。egrep和fgrep都是grep的扩展,支持更多的re元字符,fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。


  正则表达式:Regular Expression, REGEX

     由一类特殊字符及文本字符所编写的模式,其有些字符不表示其字面意义,而是用于表示控制或通配的功能;


  分两类:

     基本正则表达式:BRE 

     扩展正则表达式:ERE


  正则表达式引擎:利用正则表达式模式分析给定文本的程序;


grep家族:

   grep: Global search REgular expression and Print out the line. 支持使用基本正则表达式;

   egrep:支持使用扩展正则表达式;

   fgrep:不支持使用正则表达式;


  grep命令:

      作用:文本搜索工具,根据用户指定的”pattern(过滤条件)“对目标文本逐行进行匹配检查;打印出符合条件的行;

      模式:由文本字符及正则表达式元字符所编写的过滤条件;

  Grep命令的使用:

      grep  [OPTIONS]  PATTERN  [FILE...]


    常用选项:

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

            -i:忽略字符大小写;

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

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

            -E:支持扩展的正则表达式;

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

   在grep命令中正则表达式元字符代表大含义:

    基本正则表达式元字符:

     字符匹配:

       .:匹配任意单个字符;

 

wKiom1bje4PSG1EAAAAbmpOjJ20874.png


     任意匹配

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

 

wKiom1bje5KhtRI8AAAdB17wYfk373.png


   匹配范围内的单个字符,只要包含即可,如红色字体

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

 

wKiom1bje6rR00JVAAAmUhJfb-Y479.png


不包括abc都属于范围之内,如红色字体

    例如:[:digit:]数字,[:lower:]所有小写字母, [:upper:]所有大写字母, [:alpha:]所有的字母包括大小写, [:alnum:]字母和数字, [:space:]空白字符, [:blank:]空白字符, [:punct:]符号字符等,这里我就不一一说明了

       :可通过使用命令 ~]#man 7 glob 命令来查看更多的字符的含义



      匹配次数:

        使用方式:

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


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

        grep "x*y":

        Xxxyabc    ,yabc    ,abcxy   ,abcy这些结果都符合

    Eg:[root@buck ~]# grep "a*p" /etc/passwd

     结果如下:红色字体展现

wKioL1bjfFnDENFhAAAa-Mrws8w316.png

 

   .*:任意长度的任意字符;例子如上面“.的例子

 

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

      grep "x\+y":

        Xxxyabc  yabc(不符合)   abcxy    abcy(不符合)

      Eg:         

 

wKioL1bjffKxk6_SAAAeLCYsNtA234.png


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

         grep "x\?y":

          xxxyabc, yabc  ,abcxy  ,abcy都符合

     eg:       注:此图只是未截出含有ap的行

 wKioL1bjfd-AYQPfAAAg8SFrHeo598.png

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

      grep "x\{2\}y":

         xxxyabc(符合) ,Yabc(不符合),  abcxy(不符合),  abcy(不符合)

     Eg:如下红色字体

wKiom1bjeEewqc88AAAhJfg3Jgs982.png

 

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

                         grep x\{2,3\}y 

     Eg:如下红色字体

 

wKioL1bjfJXhdDJvAAAdWtnhEsA343.png


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

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

    例子与上面的类同


   位置锚定

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


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

       Eg:以apple开头的行被检测出来显示

wKiom1bjeEeAEtJ4AAAc9QkG8-k937.png

 

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

      Eg: 以bash结尾的行显示出来

wKiom1bjeEbA89vBAAAZ_xCgzQo646.png

 

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

     ^$:空行;

     ^[[:space:]]*$:

   例子与上面雷同


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

 

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

   eg:如下红色字体

wKiom1bjfESAhvpLAAAdWtnhEsA842.png

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

      \<PATTERN\>:单词锚定;

    eg:

wKioL1blBkaQVMOuAAAf8WtbSRg159.png

练习:

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

wKioL1blCB_AmUp8AAAisH49iJc930.png

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

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

wKioL1blCpGgOpm1AAAjOBYNG4I449.png

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

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

wKioL1blCqnivOYRAAAaMzkTxI8000.png

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

~]# netstat -tan | grep "LISTEN[[:space:]]*$"

wKiom1blCjjiCjzqAAAZsYdvq68904.png

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

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

wKioL1blCtXAbDUiAAALeoc0UBk405.png

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

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

wKiom1blCl_wKYZmAAAGFXycxPQ903.png

  分组与引用:

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


      Note:分组括号中的模式匹配到的字符会被正则表达式引擎自动记录于内部的变量中,这些变量是\1, \2, \3, ...

      eg:

        pat1\(pat2\)pat3\(pat4\(pat5\)pat6\)

说明:

  \n:模式中第n个左括号以及与之匹配的右括号之间的模式所匹配到的字符串;(不是模式,而是模式匹配的结果)


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

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

   ……

  eg:

    He love his lover

    He like his lover

    He love his liker

    He like his liker


   l..e.*l..er

其结果为:He love his lover

          He like his lover

          He love his liker

          He like his liker

  \(l..e\).*\1r

其结果为:He love his lover

          He like his liker


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


  常用选项之二:

       -E, --extended-regexp:支持使用扩展正则表达式

       -F, --fixed-strings:支持使用固定字符串,不支持正则表达式,相当于fgrep;

       -G, --basic-regexp:支持使用基本正则表达式;

       -P, --perl-regexp:支持使用pcre正则表达式;


      -e PATTERN, --regexp=PATTERN:多模式机制;

      -f FILE, --file=FILE:FILE为每行包含了一个pattern的文本文件,即grep script;


      -A NUM, --after-context=NUM

      -B NUM, --before-context=NUM

      -C NUM, -NUM, --context=NUM


egrep:  支持使用扩展正则表达式的grep命令,相当于grep -E;

   语法:

       egrep [OPTIONS] PATTERN [FILE...]


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

    字符匹配:

    .:任意单个字符

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

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

例子与上面介绍grep的例子雷同,这里就不一一列出

   匹配次数:

     *:任意次;

     ?:0次或1次;

     +:1次或多次;

    {m}:匹配m次;

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

    {0,n}

    {m,}


   位置锚定:

      ^:行首

      $:行尾

      \<, \b:词首

      \>, \b:词尾


    分组及引用:

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

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

       或者:

          a|b:a或者b

          C|cat:表示C或cat

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

说明:egrep的正则表达式中的例子与grep中的基本相同,这里就不一一列出


练习:

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

~]# egrep -v "bash$" /etc/passwd

wKioL1blFo-TX-ogAAAcXylzsdI616.png

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

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

wKiom1blFlHwIMoSAAAPbVR4EU8337.png

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

eg:egrep “^[[:space:]][a-z]+” /etc/grub2.cfg

wKioL1blFujwy5PaAAAYFhENW-8290.png


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

wKiom1blFnGjoc-3AAALJehAAW0980.png

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

wKiom1blFoHj4JUxAAAK-Ch9jXg575.png

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

wKiom1blFo-ijAA7AAAPytiM1_g429.png

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

~]# egrep "^(s|S)" /tmp/meminfo

wKiom1blFqrhaTnMAAASbjrwBKc660.png


~]# grep "^[sS]" /tmp/meminfo

wKioL1blF0OzLboBAAAT5DYf4IA705.png


~]# grep -i "^s" /tmp/meminfo

wKiom1blFsmzjhdGAAARd6Nvkn8020.png



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

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

wKiom1blFtzTXFacAAAIvp4dyK4341.png

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

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

wKiom1blFvjR6mZaAAAETfGpHXU255.png

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

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

wKiom1blG_nxvQ7JAAAj9GdV2FI136.png

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

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

wKioL1blHJmxHMO8AAANuesMt8o240.png