Shell正则表达式

429 阅读4分钟

正则表达式

REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)

不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配

符功能是用来处理文件名,而正则表达式是处理文本内容中字符

正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等

主要用来匹配字符串(命令结果,文本内容),

通配符匹配文件(而且是已存在的文件)

  • 基本正则表达式
  • 扩展正则表达式

可以使用

man 7 regex
可以使用 man手册帮助

元字符

元字符:

字符含义
.匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[zhou]   [0-9]   []   [a-zA-Z]
[^]匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] a.z
[:alnum:]字母和数字
[:alpha:]代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:]小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:]大写字母
[:blank:]空白字符(空格和制表符)
[:space:]包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:]不可打印的控制字符(退格、删除、警铃...)
[:digit:]十进制数字
[:xdigit:]十六进制数字
[:graph:]可打印的非空白字符
[:print:]可打印字符
[:punct:]标点符号
w#匹配单词构成部分,等价于[ [:alnum:]]
W#匹配非单词构成部分,等价于[^ [:alnum:]]
S#匹配任何非空白字符。等价于 [^ fnrtv]。
s#匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。

注意:Unicode 正则表达式会匹配全角空格符

元字符点(.)

[root@localhost ~]#ls /etc/|grep rc[.0-6]
#此处的点代表字符
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@localhost ~]#ls /etc/ | grep 'rc\.'
#点值表示点需要转义
rc.d
rc.local

[root@localhost ~]# grep r..t /etc/passwd         
#r..t ..代表任意两个字符    
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
[root@localhost ~]# echo abc |grep a.c              
#表示原来的点需要加\转义
abc
[root@localhost ~]# echo abc |grep a\.c
#不加引号有时匹配会有出入
abc
[root@localhost ~]# echo abc |grep 'a\.c'          
#标准格式需要加'' 或者""

[root@localhost ~]# ls |grep '[zhou].txt'    
#匹配[]中任意一个字符
h.txt
o.txt
u.txt
z.txt
[root@localhost ~]# ls [a-d].txt                
#通配符
a.txt  A.txt  b.txt  B.txt  c.txt  C.txt  d.txt
[root@localhost ~]# ls |grep '[a-d].txt'             
#真正的小写在正则表达式中
a.txt
b.txt
c.txt
d.txt
[root@localhost ~]# ls |grep '[^a-z].txt'   
#显示非小写字母
A.txt
B.txt

[root@localhost ~]# ls |grep '[^a.z].txt'     
#[]里就是本意不需要转义

space空格
[root@localhost ]#grep [[:space:]] zhen.txt 
hhh  
jj		l
kkk  
[root@localhost ]#grep [[:space:]] zhen.txt |cat -A
hhh  $
jj^I^Il$
kkk  $

表示次数

字符含义
*#匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.*#任意长度的任意字符
?#匹配其前面的字符出现0次或1次,即:可有可无
+#匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
{n}#匹配前面的字符n次
{m,n}#匹配前面的字符至少m次,至多n次
{,n} #匹配前面的字符至多n次,<=n
{n,} #匹配前面的字符至少n次

示例:

[root@localhost ~]# echo google |grep 'go\{2\}gle'
#带表前面的o出现2次
google
[root@localhost ~]# echo gooooogle |grep 'go\{2,\}gle'  
#带表前面的o出现2次以上
gooooogle
[root@localhost ~]# echo gooooogle |grep 'go\{2,5\}gle'
#带表前面的o出现2次以上5次以下
gooooogle
[root@localhost ~]# echo goooooogle |grep 'go\{2,5\}gle'
[root@localhost ~]# 
[root@localhost ~]# echo goooooogle |grep 'go*gle'    
#表示0次到任意次
goooooogle
[root@localhost ~]# echo ggle |grep "go*gle"
ggle
[root@localhost ~]# echo gggle |grep "go*gle"    
#grep 包含最前面的g不匹配
gggle
[root@localhost ~]# echo gdadadadgle |grep "g.*gle"    
#.*代表任意匹配所有
gdadadadgle
[root@localhost ~]# echo ggle |grep "go\?gle"      
# \?一次或者0次
ggle
[root@localhost ~]# echo gogle |grep "go\?gle"
gogle
[root@[root@localhost ~]# echo google |grep "go\+gle"   
#一个以上
google
[root@localhost ~]# echo gogle |grep "go\+gle"
gogle
[root@localhost ~]# echo ggle |grep "go\+gle"
[root@localhost ~]# echo google |grep "go\?gle"

位置锚定

用来定位语句

符号含义
^#行首锚定, 用于模式的最左侧
$#行尾锚定,用于模式的最右侧
^PATTERN$#用于模式匹配整行 (单独一行 只有root)
^$#空行
^[[:space:]]*$#空白行
< 或 \b#词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
> 或 \b #词尾锚定,用于单词模式的右侧
<PATTERN>#匹配整个单词

示例:

思考过滤出不是已#号开头的非空行
[root@localhost ~]#grep "^[^#]" /etc/fstab

[root@localhost ~]#grep "^[[:space:]]*$" /etc/fstab

[root@localhost ~]#echo hello-123 |grep "\<123"
hello-123
[root@localhost ~]#echo hello 123 |grep "\<123"
hello 123

分组或其他

分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+

后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名

方式为: \1, \2, \3, ...

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

或者

或者
或者:\|

示例:

[root@localhost ~]#echo abccc |grep "abc\{3\}"
abccc

[root@localhost ~]#echo abcabcabc |grep "\(abc\)\{3\}"
#分组
abcabcabc
[root@localhost ~]#echo 1abc |grep  "1\|2abc"
#只匹配了1
1abc

[root@localhost ~]#echo 1abc |grep  "\(1\|2\)abc"
#1abc或者2abc
1abc

[root@localhost ~]#ifconfig ens33|grep netmask|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{3\}'|head -1
192.168.91.100

[root@localhost ~] ens33 |grep netmask|grep -Eo '([0-9]{1,3}.){3}[0-9]{1,3}'|head -1


[root@localhost ]#ifconfig ens33 |grep netmask|grep -Eo '([0-9]{1,3}.){4}'

扩展补充(表示字符相差不大)

表示次数

字符含义
*匹配前面字符任意次
?0或1次
+1次或多次
{n}匹配n次
{m,n}至少m,至多n次
{,n}  #匹配前面的字符至多n次,<=n,n可以为0
{n,}#匹配前面的字符至少n次,<=n,n可以为0

表示分组

() 分组
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
后向引用:\1, \2, ...
| 或者  
a|b #ab
C|cat #Ccat
(C|c)at #Catcat

注:grep

grep [选项]… 查找条件 目标文件

  • -i:查找时忽略大小写
  • -v:反向查找,输出与查找条件不相符的行
  • -o 只显示匹配项
  • -f 对比两个文件的相同行
  • -c 匹配的行数([root@localhost ky15]# grep -c root passwd 2)