一、#grep命令及正则表达式的用途

   #cat 默认对整篇文本做处理,#head,#tail允许我们对文本切头去尾,过滤一些不需要的信息,还可以搭配#sort精确显示我们所需要的行,但是这建立在我们对文本内容了解的基础之上,假如我们不了解这篇文本而又要寻找查看文本中是否有需要的关键字该怎么办?#less然后/keyword或者?keyword。那假如关键字不止一个,且需要符合一定的格式并且能够只显示有关键字的行该怎么办呢?这时我们就需要用到#grep以及正则表达式了。

二、#grep命令的用法

   #grep:global search regular expression(RE) and print out the line

   Linux中的一种文本搜索工具,能够根据指定的文本模式对目标文件进行逐行搜索,并显示能够被模式匹配到的行。

   格式:

grep[options] 'PATTERN'file,...

   常用选项:--color=auto    用颜色标示行中匹配到的内容

   -v:反向匹配,显示不能被模式匹配到的行

                   -o:仅显示被模式匹配到的字串而非整行

                   -i:不区分字符大小写

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

                   -A #:不但显示匹配行还显示匹行的下#行(#标示数字)

                   -B #:不但显示匹配行还显示匹行的上#行(#标示数字)

                -C #:不但显示匹配行还显示匹行的下、下各#行(#标示数字)

   #grep命令的强大不是因为能够精确匹配关键字,更重要的是它能够支持正则表达式,以模式的方式对文件内容进行匹配。所谓正则表达式,就是一类字符所书写出的模式(pattern),这主要依靠一些不表示字符本身的意义,用于额外功能性的描述元字符来实现。

   正则表达式有基本正则表达式和扩展正则表达式两种,#grep默认只支持基本正则表达式,要支持扩展正则表达式需要增加增加“-E”选项,或者使用#egrep命令。

注意:正则表达式的元字符和通配符要做好区分

1.基本正则表式的元字符:

   字符匹配:

       .: 任意单个字符(包括空格。若".\>"锚定词尾或".$" 则不能是空格

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

       (这项和通配符基本一致但是要注意的是正则表达式区分大小写,通配符[a-z]不区分大小写

       [0-9], [[:digit:]];[a-z], [[:lower:]];[A-Z], [[:upper:]]

       [[:alpha:]]表示字母

       [[:alnum:]]表示字母和数字

       [[:space:]]表示空格

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

       [^]:指定范围外的任意单个字符(取反的意思)

   次数匹配:用来指定匹配其前面的字符的次数

       *: 任意次(和通配符表示任意字符不同

       例如:x*y表示:xxy, xy, y, (表示其前的字符有0到无穷次)

       .*: 匹配任意长度的任意字符(表示0到无穷个元字符".",每个"." 表示一个任意字符)

       \?: 0次或1次("\"存在的意义主要是转译的意思)

       例如:x\?y表示:xy, y, xxy

       \{m\}: 匹配m次

       \{m,n\}:匹配最少m次,最多n次;m,n之间次。

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

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

   位置锚定:用于指定字符出现的位置

       ^: 锚定行首

       ^Char(字符串)

       $: 锚定行尾

       (字符串)char$

           ^$: 表示空白行

       \<char: 锚定词首,\bchar

       char\>: 锚定词尾,char\b"\"表示转译

   分组:

       \(\)

       \(ab\)*xy("\"表示转译)    

   引用:

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

       (此处需要注意的是引用匹配内容一致而非通配符复制

       \2后向引用,引用前面的第二个左括号以及与之对应的右括号中的模式所匹配到的内容

       ...

       例如\(a.b\)xy\1 表示a6bxya6b而非 a6bxyaaba6bxya7b,之类

       例如    He like his lover.

                 She love her liker.            

                 He love his lover.           \(l..e\).*\1       He love his lover

                 She like her liker.                                She like her liker

2.扩展正则表达式的元字符。(需要使用#grep -E选项或者#grep命令

   字符匹配:(和基本正则表达式一样

       .: 任意单个字符

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

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

   次数匹配:

       *:匹配其前面的字符任意次;

       ?: 匹配其前面的字符0或1次;

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

       {m}: 匹配其前面的字符m次;

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

       {m,}: 至少m次;

       {0,n}:至多n次;

   位置锚定:和基本正则表达式一样

       ^: 行首

       $: 行尾

       \<, \b: 词首

       \>, \b:词尾

   分组:

       ( ): 分组  

       |:或者,

           grep -E "conC|cat" 表示conC或者cat; grep -E "con(C|c)at"表示conCat或concat

3.特殊字符的转译

       在匹配元字符本身的意义的时候通常需要对元字符进行转译,已使它显示自己本身的意义。比方说我们要匹配"."这个字符本身而非表示任意单个字符时就需要在表达式中加"\"在其之前成为"\.",来表示要匹配"."这个字符。例如

               1.1.62.125                                                             1.1.62.125

               1.1.62.126                                                             1.1.62.126

               1.1.62.127                                                             1.1.62.127

               1.1.62.128                       "\."                                 1.1.62.128    

常用的元字符转译总结

   $:匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 \$。

   ( ):分组子表达式。要匹配这些字符,请使用 \( 和 \)。

   *:匹配前面的字符零次或多次。要匹配 * 字符,请使用 \*。

   +:匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。

   .:匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。

   [ ]标记一个中括号表达式的开始。要匹配 [,请使用 \[。

   ?匹配前面的子表达式零次或一次。要匹配 ? 字符,请使用 \?。

   \:将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如'n'匹                          配字符'n'。'\n'匹配换行符。序列'\\'匹配 "\",而 '\(' 则匹配 "("。

   ^:表示行首锚定。要匹配 ^ 字符本身,请使用 \^。

   { }:标记限定符表达式的开始。要匹配 {,请使用 \{。

   |:指明两项之间的一个选择。要匹配 |,请使用 \|。

#fgrep命令不解析正则表达式。(当然遇到元字符的时候也就不用转译了)

三、#grep命令用法举例

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

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

grep "^[sS]" /proc/meminfo

grep -i "^s" /proc/meminfo

   2、取出默认shell为非bash的用户;

grep -v "bash$" /etc/passwd | cut-d: -f1

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

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

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

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

grep "^#[[:space:]].*[^[:space:]]"  /etc/rc.d/rc.sysinit

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

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

grep "^[[:space:]].*" /boot/grub/grub.conf

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

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

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

   7、找出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])\>"

   8、查看当前系统上root用户的所有信息;

grep "^root\>" /etc/passwd

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

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

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

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

netstat -tan | grep -E --color=auto "(LISTEN|ESTABLISHED)[[:space:]]*$"

   11、取出当前系统上所有用户的shell,要求:每种shell只显示一次,且按升序显示

grep --color=auto "sh$" /etc/passwd | cut -d: -f 7 | sort -u

   12、写一个模式,能匹配主机可用的有效IP地址;(1.0.0.1--223.255.255.254)

grep -E --color=auto "\<([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])\.){2}([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>"