先介绍一下正则表达式的基本组成部分
^ 行起始标记 ^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