先介绍一下正则表达式的基本组成部分

^   行起始标记       ^tux匹配以tux起始的行

$   行尾标记	    tux$匹配以tux结尾的行

.   匹配任意一个字符    它只能匹配单个字符

[]  匹配包含在[字符]之中的任意一个字符        coo[kl] 匹配cook或cool

[^] 匹配除[^字符]之外的任意字符       9[^01]    匹配92,93...但是不匹配90或91

?   匹配之前的项1次或0次             colou?r匹配color或colour

+   匹配之前的项1次或多次               rollno9+匹配rollno9或rollno99...

*   匹配之前的项0次或多次

()  创建一个用于匹配的子串             ma(tri)?x匹配max或matrix

{n} 匹配之前的项n次                    [0-9]{3}匹配任意一个三位数

{n,}    之前的项至少需要匹配n次            [0-9]{2,}匹配任意一个两位数或更多位的数字

{n,m}   指定之前的项匹配的最小和最大次数         [0-9]{2,5}匹配两位数到五位数之间的任意一个数字

|   交替匹配|两边的任意一项                 Oct (1st | 2nd) 匹配Oct 1st或Oct2nd

\   转义符可以将上面介绍的特殊字符进行转义                     a\.b,匹配a.b,通常在.之前加上\而忽略了.的特殊意义


正则表达式模式是贪婪模式,也就是说它会尽可能的去匹配能匹配的字符串。
举个例子

cat 1.txt
#[tupian](http://www/baidu.com/1.jpg) hate you [wenjian](http://www.baidu.com/1.html)

我们要把[]和()内的内容提取出来

cat 1.txt | grep -oP '\[.+\]\(.+\)'
#[tupian](http://www/baidu.com/1.jpg) hate you [wenjian](http://www.baidu.com/1.html)

因为默认是贪婪匹配,所以‘\[.+’将整句的字符都匹配了,而不去匹配‘\]\(.+\)’
通过在 + 后面加个问号,即可实现非贪婪匹配,也就是它会尽可能少的去匹配字符

cat 1.txt | grep -oP '\[.+?\]\(.+?\)'
#[tupian](http://www/baidu.com/1.jpg)
#[wenjian](http://www.baidu.com/1.html)

接着我将[]以及()内的内容提取出来

cat 1.txt | grep -oP '\[.+?\]\(.+?\)'|sed -r 's/\[(.*?)\]\((.*?)\)/\1 \2/g'
#tupian http://www/baidu.com/1.jpg
#wenjian http://www.baidu.com/1.html

总结:?可用于实现非贪婪匹配,大多用在 * 和 + 之后

命令格式:

grep [-cinvABC] 'word' filename
-c  表示打印符合要求的行数
-i  表示忽略大小写
-n  表示输出符合要求的行及行号
-v  表示打印不符合要求的行
-o  表示只输出文件中匹配到的文本部分(需要使用扩展的正则表达式)

+ 是不支持被grep直接使用的

-A  后面跟一个数字(有无空格均可),例如-A2表示打印符合要求的行以及下面两行
-B  后面跟一个数字(有无空格均可),例如-B2表示打印符合要求的行以及上面两行
-C  后面跟一个数字(有无空格均可),例如-C2表示打印符合要求的行以及上下各两行
-E  扩展正则表达式(可减少\的使用) 如同sed中的-r选项   或直接使用 egrep 也可

-P  表示启用Perl正则表达式
grep -A2 'halt' /etc/passwd
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin

#过滤出带有某个关键字的行,并输出行号
grep -n 'root' /etc/passwd
#1:root:x:0:0:root:/root:/bin/bash
#10:operator:x:11:0:operator:/root:/sbin/nologin

#过滤出不带有某个关键字的行,并输出行号
grep -vn 'nologin' /etc/passwd
#1:root:x:0:0:root:/root:/bin/bash
#6:sync:x:5:0:sync:/sbin:/bin/sync
#7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#8:halt:x:7:0:halt:/sbin:/sbin/halt

#过滤出所有包含数字的行
grep '[0-9]' /etc/inittab
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5

#过滤出所有不包含数字的行
grep -v '[0-9]' /etc/inittab

#过滤出所有以#号开头的行
grep -v '^#' /etc/init.d/mysqld

过滤出所有以空行或以#开头的行
grep -v '^#' /etc/init.d/mysqld | grep -v '^$'

#过滤出任意一个字符和重复字符
grep 'r.o' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#operator:x:11:0:operator:/root:/sbin/nologin

cat /etc/passwd |wc -l
#19
grep '.*' /etc/passwd |wc -l
#19

echo this is a line. | grep -o '[a-z]+\.'

#指定要过滤的字符出现的次数
#{}不支持grep直接使用,需要加上\
grep 'o\{2\}' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#postfix:x:89:89::/var/spool/postfix:/sbin/nologin


#过滤出一个或多个指定的字符
#+号不支持grep直接使用,需要加上\
egrep 'oo+' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#postfix:x:89:89::/var/spool/postfix:/sbin/nologin


#也可加上-E选项
grep -E 'oo+' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#postfix:x:89:89::/var/spool/postfix:/sbin/nologin

#过滤出零个或一个指定的字符
egrep 'ooo?' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#postfix:x:89:89::/var/spool/postfix:/sbin/nologin

#过滤出子串1或字符串2
egrep 'root|mysql' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#operator:x:11:0:operator:/root:/sbin/nologin
#mysql:x:1000:1000::/home/mysql:/sbin/nologin

#egrep中()的使用
egrep '(oo)+' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#postfix:x:89:89::/var/spool/postfix:/sbin/nologin

#统计行数
egrep -c '(oo)+' /etc/passwd | grep -c
#5