Linux 命令之grep 的常见使用总结:


grep简介

Grep(Global Regular Expression Print),

它是Linux系统中一种强大的文本搜索工具,根据用户指定的文本模式去对目标文件或标准输入进行逐行查找输入,显示能够被匹配到的字符串的所在行。这是提到的文本模式(PATTERN)指得就是正则表达式,它的强大就是指对正则表达式的应用,所以学习grep主要也就是去学习正则表达式的正确使用

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


fgrep命令是用来查找一个或多个与给出的字符串或词组相匹配文件中的行。fgrep 查询速度比grep命令快,但是不够灵活:它只能找固定的文本,而不是规则表达式,这里就不再做介绍。


二、命令使用格式

grep[OPTIONS] PATTERN [FILE...]


grep[OPTIONS] [-e PATTERN | -f FILE] [FILE...]

常用的选项参数介绍(在下面的应用举例中也会对这些参数作一些解释,这里就不再举例了)

-v --invert-match -->反向显示,显示那些没有被模式匹配到的其它行

-o --only-match -->仅显示被模式匹配到的字符串,还非整行

-i  --ignore-case -->不区分字符大小写

-n --line-number -->打印出匹配到的所在行的行号 wc -l 一样效果

-E --extended-regexp -->支持扩展的正则表达式,即egrep[OPTIONS] PATTERN

-A # --after-context=#  -->显示匹配到行及所在行的下面#

-B # --before-context=# -->显示匹配到的行及所在行的上面#

-C # -->显示匹配到的行及所在行的上下各#

--color=auto 对匹配到的文本作出高亮显示


三、grep 的使用详解

  1. 先就命令的使用及各参数的意义介绍使用

准备的配置文件,先以/etc/passwd 为例

1root:x:0:0:root:/root:/bin/bash

 2 bin:x:1:1:bin:/bin:/sbin/login

 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

 4adm:x:3:4:adm:/var/adm:/sbin/LOGIN

 5operator:x:11:0:operator:/root:/sbin/nologin

  1. grep  "root" /etc/passwd

结果显示:

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

显示结果为root 所在的完部行

  1. Grep   "login" /etc/passwd

结果显示:

bin:x:1:1:bin:/bin:/sbin/login

daemon:x:2:2:daemon:/sbin:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

因为其中每一样都有字符login

  1. Grep -n "login" /etc/passwd

2 bin:x:1:1:bin:/bin:/sbin/login

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

5 operator:x:11:0:operator:/root:/sbin/nologin

相信很容易看出与(b)有什么不同

  1. Grep -n --color=auto -v "login" /etc/passwd(选项是很可以累加的)

1:root:x:0:0:root:/root:/bin/bash

4:adm:x:3:4:adm:/var/adm:/sbin/LOGIN

  1. Grep -n --color=auto -v -I

1:root:x:0:0:root:/root:/bin/bash


总结:从上面的搜过结果可以看出grep 是对特点的字符串进行搜索匹配,但是如果只是简单的字符串跟普通的搜索功能没有什么两样,而且字符中相似度很高也不能很精确的匹配到想要的行数,

比如上例中只想要以root 开头的行、或者只想要用户ID 1 的整行、或者是用户命用bash 名一致的用户可以想像简单的字符串匹配是完整不了对于特定内容在文件里面的查找,所以就需要要一种灵活的匹配模式即规则去处理文件中的字符,来获取想要得到的信息,而正则表达式所做的就是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串


四、grep 、扩展grep 及与正则表达式结合的使用

正则表达式的强大就是在于其强大的各种字符,下面介绍一些grep 中常用的基本正则表达式的字符


基本正则表达式:

  • 字符匹配

       a.   .    ----> 匹配.所在位置的任意单个字符

如文件:

a*b

Acb

a/b

A  b

Ab

a.d

Grep  -v "a.b"  /File/Path

结果:

AB

a.d

        b. [ ] ---->指定范围内的任意单个字符

:[a-z] az中任意单个字符

    [Ab?D] asdfasf??asfasDaA

注意:grep 是工作于贪婪模式的,如果一行中出现模式命中的字符刚会最大限度的匹配,即把匹配到的内容全部显示出来

  • 了在不同国家的字符编码中保持一至,POSIX(The     Portable Operating System Interface)增加了特殊的字符类

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

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

[:digit:]:代表数字,即 0-9

[:alpha:]:代表任何英文大小写字母,即 a-z A-Z

[:alnum:]:代表英文大小字符及数字,即 0-9 a-z A-Z

[:space:]:代表空格键与Tab按键

[:punct:]:代表标点符号,即 “ ;? #$


  • 次数匹配(用来指定其前面的第一个任意字符的次数)

        a.  *   ---->对其前面的第一个任意字符的匹配任意次数

              .* ---->任意长度的任意匹配

                   1.  如:grep  "as3c*" /File/Path

                            结果: As3c

         As3ccccc

                   2.  Grep ".*"  /File/Path 则表示搜索全部

                   3.  grep -n 'ooo*' regular_express.txt 搜索两个o以上的字符串前两个o一定存                              在,第三个o可没有,也可有多个。


        b.  \? ---->对其前面的第一个任意字作0次或1次匹配

           如:Grep  "as\?" /File/Path

       as

       ass

        c.  \{m\}    ---->对其前面的第一个任意字符作m次匹配

        e.  \{m,n\}  ---->对其前面的第一个任意字符作mn次匹配

        f.  \{m,\}    ---->对其前面的第一个任意字符作至少m次匹配

        g.  \{,n\}    ---->对其前面的第一个任意作至多m次匹配


  • 位置锚定符(用来对指定字符在文件中出现的位置作指定)

常见行首锚定、行尾锚定、单词锚定,对于锚定的方式又可分为两类:

i. 字符锚定(用于指定字符出现的位置)

       a.  ^  ---->用于锚定行首

如:锚定以字母S 开头,且至少有5个连续的行

Grep "^[Ss]\{5,\}" /File/Path

       b.  $ ---->用于锚定行尾

                     如:锚定以非数字开头且后面跟着一个或多个空格,又不能以字母结尾的行

Grep "^[^[:digit:]][[:space:]]\{1,m}$" /File/Path

锚定空白行

Grep "^$" /File/Path

   ii. 单词锚定(用于锁定一个字符串的词头和词尾)

\< ---->锚定词首

\> ---->锚定词尾

  如:在/etc/passwd

查找root 用户的所在行

Grep "^\<root\>" /etc/passwd  


   iii. 分组元字符

\( \) ---->以括号里面的字任为一个单元组进行匹配或引用

如要搜索 glad 或 good 可以这样'g(la|oo)d'

()的好处是可以对小组使用 + ? * \1等。

比如要搜索A和C开头结尾,中间有至少一个(xyz) 的串,可以这样 : 'A(xyz)+c'


   iv.   引用


\1 ----> 后向引用第一个左括号以及与之对应的右括号的模式所匹配到的内容

\2 ---->同上后向引用第二个括号里面的内容

注意:这里引用的是前面第#个括号里面匹配到的内容而非那个括号里面的表达式


    如:grep "ap\(pe\)r.*\1"

如果ap被匹配,则ap就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个pe(\1),找到就显示该行。



扩展正则表达式

注意:grep只支持基础表达式,而egrep 支持扩展的, 其实 egrep 是 grep -E 的别名而已。因此grep -E 支持扩展正则。

  • 字符匹配(与基本正则一样)

.   ---->任意单个字符

[ ] ---->指定范围内任意单个字符

[^] ---->指定范围外的任意单个字符

  • 次数匹配

* ---->其前的字符任意次

---->其前的字符0次或1(基本正则中没有)

+ ---->匹配其前字符至少一次

注意:因为{}bash 中有特殊用外,所以在基本正则里面需要转义即\,但是在扩展正则中就不用转义可以直接识别

{m} ---->匹配其前字符

{m,n} ---->匹配其前字符m

{m,} ---->至少m

{0,n} ---->至多n

  • 锚定

^ ---->锚定行首

$ ---->锚定行尾

\<,\b    ---->锚定词首

\>,\b    ---->锚定词尾


下面给出一些具体的实例:

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

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

    #grep -E "^#[[:space:]]+[^[:space:]]+" /etc/rc.d/rc.sysinit


  1. 区配/boot/grub/grub.conf中以至少一个空白字符开头的行,并且删除行中的空白显示

    # grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\} | cut -d [[:blank:]]"/boot/grub/grub.conf

    #grep -E "^[[:space:]]+" /boot/grub/grub.conf | cut -d [[:blank:]]


  1. 找出/etc/passwd文件中一位数或两位数;

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

#  Egrep "\<([0-9]|[1-9][0-9])\>"  /etc/passwd   //注意:这里一定要加括号分组如果不加就是以\<[0-9] 或者[1-9][0-9]\> 不能准确的锚定一个组数字,会造成匹配不正确,如者是改成如下也可以实现,逻辑是一样的,可以对比的学习一下

#egrep "\<\[0-9]\>|\<[1-9][0-9]\>" /etc/passwd


  1. 取出默认shell为bash的且其ID号最大的用户;

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


  1. 找出ifconfig命令结果中的1到255之间的整数;

    #ifconfig | grep -E --color=auto"\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"

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


  1. 添加用户bash和testbash、basher,而后找出当前系统上其用户名和默认shell相同的用户;

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

#grep-E "(^[[:alnum:]]+)\>.*\1$" /etc/passwd


  1. 找出netstat     -tan命令执行的结果中以“LISTEN”或“ESTABLISHED”结尾的行;

          #netstat -tan | grep -E"(LISTEN|ESTABLISHED)\>[[:space:]]*$" //注意:不要以LISTEN或者ESTABLISHED来锚定行尾,      细心的朋友可以cat -e 打印看一下,后面还有许多空格字符


h.  匹配该IP 地址(1.0.0.1--223.255.255.254)

         #egrep"\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>"


                                                                       ----欢迎指导