我们经常会有处理一些文本的需求,Linux下著名的文本处理三剑客:grep、sed、awk,这一篇讲最简单的grep,sed和awk我们后面会讲到。那么在讲解grep之前,我们先说一下正则表达式,这是在使用grep,sed等命令时大部分情况会用到的基础内容。
一、正则表达式概念
二、正则表达式详解
三、扩展正则表达式详解
四、grep命令详解
五、grep结合正则实例
一、正则表达式概念(regex、regexp)
正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
正则表达式通常用于两种任务:1.验证,2.搜索/替换。用于验证时,通常需要在前后分别加上^和$,以匹配整个待验证字符串;搜索/替换时是否加上此限定则根据搜索的要求而定,此外,也有可能要在前后加上\b而不是^和$。
以上内容来源于百度百科和http://deerchao.net/tutorials/regex/common.htm
二、基本正则表达式详解
正则表达式 由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面列出一些常见的元字符:
1. 匹配字符
.: 匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
字符集合:[:digit:], [:lower:], [:upper:], [:punct:], [:space:], [:alpha:], [:alnum:]
ps:这些字符集合含义在我上篇博客Bash特性总结中第6章Glob通配符有
2. 匹配次数(贪婪模式)
*: 匹配其前面的字符任意次
.*: 任意长度的任意字符
\?: 匹配其前面的字符1次或0次
\{m,n\}:匹配其前面的字符至少m次,至多n次
3. 位置锚定
^: 锚定行首,此字符后面的任意内容必须出现在行首
$: 锚定行尾,此字符前面的任意内容必须出现在行尾
^$: 空白行
\<或\b: 锚定词首,其后面的任意字符必须作为单词首部出现
\>或\b: 锚定词尾,其前面的任意字符必须作为单词的尾部出现
4. 分组
\(\):如\(ab\)* # 此处的*修饰的前面括号里的内容,也即ab
后向引用
\1: 引用第一个左括号以及与之对应的右括号所包括的所有内容
\2: 引用第一个左括号以及与之对应的右括号所包括的所有内容
三、扩展正则表达式详解
扩展正则表达式大部分与基本正则表达式相同,在此基础上新增了一些次数匹配相关的元字符:
?:匹配其前字符0次或1次
+:匹配其前面的字符至少1次
{m,n}:匹配其前字符至少m此,至多n次,不用加\转义
():如(ab),将ab作为一个分组
|:或者,也即要么是|左边的部分,要么是|右边的部分
四、grep命令详解
grep, egrep, fgrep - print lines matching a pattern # 打印匹配指定模式的行 SYNOPSIS grep [options] PATTERN [FILE...] grep [options] [-e PATTERN | -f FILE] [FILE...] -i:忽略大小写 -n:在显示符合范本样式的那一列之前,标示出该列的编号 -v:被模式匹配到的反而不显示,即反向查找 -o:只显示被模式匹配到的内容 --color:搜索内容高亮显示 -i:忽略字符大小写 -E:使用扩展正则表达式,相当于egrep命令 -A #:除了被匹配到的,同时显示被模式匹配到的后n行 -B #:除了被匹配到的,同时显示被模式匹配到的前n行 -C #:除了被匹配到的,同时显示被模式匹配到的前后n行
1.按模式匹配到字符串后显示行号
[root@soysauce ~]# grep -n "b..h$" /etc/passwd # 取出以b开头且中间任意两个字符h结尾的行,并显示行号 1:root:x:0:0:root:/root:/bin/bash 33:mysql:x:101:158::/home/mysql:/bin/bash 34:apache:x:102:159::/home/apache:/bin/bash 36:hadoop:x:501:501::/home/hadoop:/bin/bash
2.只显示没有被模式匹配到的行
[root@soysauce ~]# grep -v "nologin$" /etc/passwd # -v反向查找,匹配到的字符串反而不显示 root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt news:x:9:13:news:/etc/news: mysql:x:101:158::/home/mysql:/bin/bash apache:x:102:159::/home/apache:/bin/bash hadoop:x:501:501::/home/hadoop:/bin/bash
3.只显示被匹配到的字符串,并不显示整行
[root@soysauce ~]# grep -o "root" /etc/passwd # -o只显示匹配到的字符串 root root root root
4.匹配到的字符串给予高亮显示
[root@soysauce ~]# grep --color "r..t" /etc/passwd root:x:0:0:root:/root:/bin/bash # 额,这里高亮效果没显示出来,你在终端上敲此命令就可以看到效果了 operator:x:11:0:operator:/root:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
5.使用扩展的正则表达式
[root@soysauce ~]# grep -E --color "root|ftp" /etc/passwd # 查找包含root或ftp的行 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
6.按模式匹配到行之后,其后面n行也一起显示
[root@soysauce ~]# grep -A 2 "root" /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin # 这是第一次匹配到root时所在行的后两行 daemon:x:2:2:daemon:/sbin:/sbin/nologin -- operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin # 这是第二次匹配到root时所在行的后两行 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
7.按模式匹配到行之后,其前面n行也一起显示
[root@soysauce ~]# grep -B 2 "root" /etc/passwd root:x:0:0:root:/root:/bin/bash # 因为第一次匹配到的root是第一行,所以就没有前2行 -- news:x:9:13:news:/etc/news: uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin # 这是第二次匹配到root时所在行的前两行 operator:x:11:0:operator:/root:/sbin/nologin
8.按模式匹配到行之后,其前后n行也一起显示
[root@soysauce ~]# grep -C 2 "root" /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin # 因为第一次匹配到的root是第一行,所以就没有前2行,只有后两行 daemon:x:2:2:daemon:/sbin:/sbin/nologin -- news:x:9:13:news:/etc/news: uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin # 此行是被模式匹配到的行 games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
五、grep结合正则实例
1、显示/proc/meminfo文件中以不区分大小的s开头的行
[root@soysauce ~]# grep "^[sS]" /proc/meminfo SwapCached: 0 kB SwapTotal: 0 kB SwapFree: 0 kB Slab: 82072 kB [root@soysauce ~]# grep -i "^s" /proc/meminfo # 与第一条命令相同 [root@soysauce ~]# egrep "^(s|S)" /proc/meminfo # 与第一条命令相同
2、取出默认shell为/bin/bash的用户列表
[root@soysauce ~]# grep "bash$" /etc/passwd | cut -d: -f1 root mysql apache hadoop
3、取出默认shell为bash,且其用户ID号最小的用户的用户名
[root@soysauce ~]# grep "bash" /etc/passwd | sort -n -t: -k3 | cut -d: -f1 | head -1 root
4、显示/etc/inittab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意非空白字符的行
[root@soysauce ~]# egrep "^#[[:space:]]+[^[:space:]]" /etc/inittab # 内容过长,只截取少部分 # inittab This file describes how the INIT process should set up # the system in a certain run-level. # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> # Modified for RHS Linux by Marc Ewing and Donnie Barnes # Default runlevel. The runlevels used by RHS are: # 0 - halt (Do NOT set initdefault to this)
5、显示/etc/inittab中包含了:一个数字:(即两个冒号中间一个数字)的行
[root@soysauce ~]# egrep ":[[:digit:]]:" /etc/inittab id:3:initdefault: l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 l3:3:wait:/etc/rc.d/rc 3 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6 x:5:respawn:/etc/X11/prefdm -nodaemon
6、显示/boot/grub/grub.conf文件中以一个或多个空白字符开头的行
[root@soysauce ~]# egrep "^[[:space:]]+" /boot/grub/grub.conf root (hd0,0) kernel /boot/vmlinuz-2.6.18-308.el5 ro root=LABEL=/ clock=tsccount ide0=noprobe initrd /boot/initrd-2.6.18-308.el5.img
7、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行
[root@soysauce ~]# egrep "^([[:digit:]]).*\1$" /etc/inittab 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6
8.ifconfig命令中四位点分十进制数截取
[root@soysauce ~]# ifconfig|egrep --color -o '(\b([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b.){3}\b([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b' x.x.x.x x.x.x.x x.x.x.x x.x.x.x x.x.x.x x.x.x.x 127.0.0.1 255.0.0.0
8.ifconfig命令中ip地址截取
[root@soysauce ~]# ifconfig |egrep -o --color '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>){2}\.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>' x.x.x.x x.x.x.x 127.0.0.1
附:常用正则表达式