一、文本搜索工具grep

(一)grep简介

       Linux上常用的三个文本处理工具被人们称为Linux文本处理三剑客,他们分别是:

        1.grep(egrep,fgrep):文本搜索工具,基于“pattern”对给定的文本进行搜索操作。

        2.sed:stream editor,流编辑器,行编辑工具,文本编辑工具。    

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

    他们都是很优秀的文本处理工具。现在,我就重点介绍下grep。

        grep:global search regular expression and print out the line.支持使用正则表达式。

        egrep: 支持使用拓展正则表达式。    

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


(二)grep的使用

    grep命令:文本搜索工具,根据用户指定的“partern”(过滤条件)对目标文本逐行进行匹

              检查,并打印出符合条件的行。

        格式:grep [OPTIONS] PATTERN [FILE...]

        常用选项:

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

                -i:忽略字符大小写

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

                -v,--invert-match:反相匹配

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

                -E:支持拓展正则表达式,相当于egrep

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

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

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

                -e PATTERN,--REGEXP=PATTERN:多模式机制

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

                -A NUM,--after-contex=NUM:显示匹配到的文本后NUM行

                -B NUM, --before-context=NUM:显示匹配到的文本前NUM行

-C NUM, -NUM, --context=NUM:显示匹配到的文本前后各NUM行

    egrep命令:支持使用拓展正则表达式的grep命令,相当于grep- E
         格式grep [OPTIONS] PATTERN [FILE...]


二、正则表达式

    在上文中我们反复提到正则表达式,那么正则表达式究竟是什么呢?   

    正则表达式:Regular Expression, REGEX。是由一类特殊字符及文本字符所编写的模式,其有些字

                符不表示其字面意义,而是用于表示控制或通配的功能;

    正则分为两类:

基本正则表达式:BRE 

扩展正则表达式:ERE

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

(一)基本正则表达式

   (1)基本正则表达式的元字符

      1.字符匹配

        .:匹配任意单个字符

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

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

            [[:upper:]]:所有大写字母;

            [[:lower:]]:所有小写字母;

            [[:digit:]]:所有的数字;

            [[:alpha:]]:所有字母;

            [[:alnum:]]:所有字母和数字;

            [[:space:]]:空白字符;

            [[:punct:]]:标点符号;

           可以通过使用man 7 glob命令来查看

      2.匹配次数

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

        式。

            *:匹配前面的字符人一次(0,1或多次)
                     .*:匹配任意长度的任意字符

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

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

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

            \{m,n\}:前面的字符出现m到n次

            \{0,n\}:前面的字符出现至多n次

            \{m,\}:前面的字符出现至少m次

      3.位置锚定

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

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

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

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

                ^$:空行;

                ^[[:space:]]*$:

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

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

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

     \<PATTERN\>:单词锚定;

       4.分组与引用:

            \(PATTERN\):将此PATTERN匹配到的字符当作一个不可侵害整体进行处理;注意:分组括号中的模式匹配到的字符会被正则表达式引擎自动记录于内部的变量

                      中,这些变量是\1, \2, \3, ...

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

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

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

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

……

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

   (2)拓展正则表达式的元字符

      1.字符匹配

        拓展正则表达式的字符匹配于基本正则表达式完全一致此处不再赘述。

      2.匹配次数

        拓展正则表达式的匹配次数与基本正则表达式很相似,只是省略了基本正则表达式中的转意符

            *:匹配前面的字符人一次(0,1或多次)
                     .*:匹配任意长度的任意字符

            +:匹配前面的字符至少一次

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

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

            {m,n}:前面的字符出现m到n次

            {0,n}:前面的字符出现至多n次

            {m,}:前面的字符出现至少m次

      3.位置锚定:拓展正则表达式的位置锚定与基本正则表达式完全一致此处不再赘述。

      4.分组与引用:拓展正则表达式的分组与引用与基本正则表达式完全一样此处不再赘述。

      5.或者

            a|b:a或者b    

            c|cat:c或者cat

            (C|c)at:Cat或者cat

    总结:拓展正则表达式与基本正则表达式十分相似,只是拓展正则表达式取消了匹配次数中的转

          义符,添加了或者这一概念。


三、grep与正则表达式的应用

    上面介绍了grep与正则表达式,那么我们怎么在操作中使用它们呢?下面我们就来练习一下。

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

grep -v "bash$" /etc/passwd

wKioL1blG0bQwOQqAAC2nUtVAhY941.png

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

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

wKiom1blG3LgcZfQAABqia1rj6s061.png

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

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

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

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

wKiom1blHKOh8LUJAAApqwzdzT4556.png    

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

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

wKioL1blHaODL2ZBAAAfHBvGj2g802.png




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

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

                                      wKiom1blHcjSm4C-AAAZgLQUnB0150.png

 下面的练习请使用egrep命令来完成。    

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

 egrep "^(s|S)" /tmp/meminfo

 grep "^[sS]" /tmp/meminfo

 grep -i "^s" /tmp/meminfo

wKiom1blHpLhAiX2AAAlKGdKqxI779.png

      







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

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

wKiom1blHvbxXU5aAAAiMi0P9Ug130.png

         



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

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

wKiom1blH4KCeuDTAAAXorOZnQk784.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])\>"

wKiom1blH9nxmarPAABVXFTxLCw606.png

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

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

wKioL1blIMeRTc1aAAAlO_K4ffE219.png