首页 > 代码库 > Linux文本处理工具——Grep

Linux文本处理工具——Grep

Grep简介

    全名:Global search Regular expression and Print out the line.

    功能:文本搜索工具,根据用户指定的文本模式(搜索条件)对目标文件进行逐行搜索,显示能匹配到的行。


    Linux的三大文本处理工具之一,可以说学好grep命令无疑是重要的,可以说学好grep也是不容易的,因为grep里面要用到最烦人的正则表达式。

 

grep语法格式

    grep [option]... ‘PATTERN‘ FILE...


    [option]:表示可以跟选项,中括号表示可以省略,…表示可以跟多个选项


    PATTERN:这个可以跟上模式,也就是可以使用正则表达式来进行匹配搜索,正则表达式下面会细说。


    FILE…:表示后面可以跟上多个进行文本搜索的文件


    Eg:查找/etc/passwd这个文件里面包含root字眼的行,从下图可以看出,打印出来的行,每一行的内容都包含有root字眼,这就是grep的作用

image

    

    W注意点:模式当中一但包含元字符一定要用‘‘或""号引起来,单双引号都可以、只不过如果其中出现了变量、并且我们希望做变量替换的话那就要使用""双引号了、否则可以不加区分的使用。

 

常用选项[option]

    --color=auto:用颜色显示出匹配的内容

image

    

    可以看到,被匹配的内容都通过颜色高亮出来,这样很有助于我们去检查给予的匹配条件有没有符合我们的要求。所以平时都要带上这个选项,但是又不想每次都输入,就可以在~/.bashrc里面加入alias grep=‘grep --color=auto‘就可以了。

 

    -v: 反向选取:就是表示取反,把没有匹配到的行显示出来

image

 

    -i:匹配的时候,对于匹配的条件忽略字符大小写

image

 

 

正则表达式的简介

    如果grep命令只是可以匹配给定的具体字符的话,那估计grep就没有这么大的魔力了,当然也不敢号称是三大文本处理工具之一了。想用好grep,就要学会怎么样让grep去进行模式(就是正则表达式)匹配,这就脱不开正则表达式,虽然正则表达式很烦人,但是学好了,作用是非常大。

    概念:是一类字符所书写的模式,其中许多字符不表示其字面意义,而是表达控制或通配等功能,这类字符就是所谓的元字符。

    混淆点:正则表达式不是由bash shell环境去解释的,而是通过正则表达式引擎来解释,也就是说命令自己要去实现和解释正则表达式。

    正则表达式可以分为两种:基本正则表达式和扩展正则表达式,接下来就会细说这两者。

 

基本正则表达式

    正则表达式不外乎是一堆元字符组成的模式,对于基本正则表达式,可以把元字符分为四个方面

 

    1、 字符匹配:用来匹配相应的字符的,比如是数字还是字母一类的。。。

        . 匹配任意单个字符

            Eg: grep "r..t" /etc/passwd 表示匹配以r字母为首,中间出现任意两个字符,然后紧跟t字母的子串

image

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

            [ade] 这样就表示,可以匹配a或者d或者e

            对于中括号,这里还有一些特殊含义的字符

            [0-9], [[:digit:]] 数字

            [a-z], [[:lower:]] 小写字母

            [A-Z], [[:upper:]] 大写字母

            [[:space:]] 空格

            [[:punct:]] 标点符号

            [[:alpha:]] 字母

            [[:alnum:]] 字母+数字

            Eg:grep “[0-9][0-9]” /etc/fstab 表示找两个数字一起的子串

image

            [^] 表示取反,也就是非

 

    2、 次数匹配元字符:用于实现指定其前面的字符所能够出现的次数

        *: 任意长度,它前面的字符可以出现任意次

            例如:x*y 可以用来匹配xxy, xyy, y,

         \?: 0次或1次,它前面的字符是可有可无的

            例如:x\?y 可以用来匹配xy, y, ay

        \{m\}: m次,它前的字符要出现m次

            例如:x\{2\}y     可以用来匹配xy, xxy, y, xxxxy, xyy

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

            例如:x\{2,5\}y 可以用来匹配xy, y, xxy

        \{m,\}:至少m次

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

        \+:至少1次

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

        Eg:grep “[0-9]\{1,3\}” /etc/fstab 表示匹配数字至少出现一次,至多出现三次的子串

image

 

    

    3、 位置锚定:

        ^: 行首锚定;

            写在模式最左侧,表示必须从行首开始匹配

        $: 行尾锚定:

            写在模式最右侧,表示必须以这个结尾

        \<: 词首锚定:

            出现于单词左侧,表示必须从词首开始匹配

        \>: 词尾锚定:

            出现于单词右侧,表示必须以这个作为单词结束

        \b:可以用来代替\<和\>

            Eg:查找/etc/fstab中以#开头的内容

image

 

    4、 分组:

        \(\) 例如:\(ab\)*

        \(\)还可以用来引用:分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被引用

        \#: 引用第n个括号所匹配到的内容,而非模式本身

        Eg:从文本中匹配同一行中有连续两个相同子串的内容

image

 

 

扩展正则表达式简介

    Grep如果要使用扩展正则表达式的话,要带上-E的选项,或者使用egrep命令也可以。

    扩展正则表达其实和基础正则表达式一样,但是扩展正则表达的好处就是及少使用转义的符号,不会被一大堆的转义符号搞得晕头转向的。

    使用扩展正则表达式,还多了一个功能,就是可以使用具备或功能的元字符(|),它的功能很好用,很多情况就是有了或功能,正则表达式的模式会变得比较短小。


扩展正则表达式

    跟基本正则表达式一样,也总共分四类

    1、 字符匹配

        . 匹配任意单个字符

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

        [ade] 这样就表示,可以匹配a或者d或者e

            对于中括号,这里还有一些特殊含义的字符

        [0-9], [[:digit:]] 数字

        [a-z], [[:lower:]] 小写字母

        [A-Z], [[:upper:]] 大写字母

        [[:space:]] 空格

        [[:punct:]] 标点符号

        [[:alpha:]] 字母

        [[:alnum:]] 字母+数字

        [^] 表示取反,也就是非


    2、 次数匹配元字符

        *:任意次

        ?: 0次或1次

        +: 至少1次;

        {m}: 精确匹配m次

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

        {m,}:至少出现m次

        {0,n}:至多出现n次


    3、 位置锚定

        ^:行首锚定

        $:行尾锚定

        \<, \b:词首锚定

        \>, \b:词尾锚定


    4、 分组

        ()

        引用:\1, \2, \3


    5、 或者

        a|b: a或者b

        eg:取/etc/passwd文件里面带有root或者dump的内容

image

 

 

Fgrep的使用

    fgrep:它不支持正则表达式,你找想什么具体的字符就写什么具体的字符,所以它的查找速度也是最快的;

    例:fgrep "/bin/bash" /etc/passwd

image

 

 

练习测试

    这里直接给出题目和结果,通过练习可以让我们更好的掌握知识点


    基本正则表达式练习:

        1、显示/proc/meminfo文件中以大写或小写S开头的行;

            # grep -i ‘^s‘ /proc/meminfo

            # grep ‘^[Ss]‘ /proc/meminfo

            # grep -E ‘^(S|s)‘ /proc/meminfo


        2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;

            # grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1


        3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;

           进一步:仅显示上述结果中其ID号最大的用户;

            # grep "/bin/bash$" /etc/passwd | sort -t: -k3 -n | tail -1 | cut -d: -f1


        4、找出/etc/passwd文件中的一位数或两位数;

            # grep "\<[0-9][0-9]\?\>" /etc/passwd

            # grep "\<[0-9]\{1,2\}\>" /etc/passwd


        5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;

            # grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf


        6、显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;

            # grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit


        7、找出netstat -tan命令执行结果中以‘LISTEN‘结尾的行;

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


        8、添加用户bash, testbash, basher, nologin(SHELL为/sbin/nologin),而找出当前系统上其用户名和默认shell相同的用户;

            # grep "^\([[:alnum:]]\{1,\}\):.*\1$" /etc/passwd


        9、扩展题:新建一个文本文件,假设有如下内容:

            He like his lover.

            He love his lover.

            He like his liker.

            He love his liker.

            找出其中最后一个单词是由此前某单词加r构成的行。

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



    扩展表达式练习

        10、显示当前系统上root、fedora或user1用户的默认shell;

            # grep -E "^(root|fedora|user1):" /etc/passwd | cut -d: -f7


        11、找出/etc/rc.d/init.d/functions文件中某单词后跟一组小括号“()”行;

            # grep -o -E "\<[[:alnum:]]+\>\(\)" /etc/rc.d/init.d/functions


        12、使用echo命令输出一个路径,而后使用grep取出其基名;

            # echo "/etc/sysconfig/" | grep -o -E "[[:alnum:]]+/?"

            # echo "/etc/sysconfig/" | grep -o -E "[^/]+/?$" | cut -d/ -f1


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

            # ifconfig | grep -o -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"


        14、挑战题:写一个模式,能匹配合理的ipv4地址;

            1.0.0.1-239.255.255.255

本文出自 “LC的IT之路” 博客,请务必保留此出处http://leezc.blog.51cto.com/8650393/1437657