shell编程之正则表达式详解

Posted givenchy_yzl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程之正则表达式详解相关的知识,希望对你有一定的参考价值。

正则表达式

1储备知识

什么是正则表达式?
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式由元字符组成,通常被用来检索、替换那些符合某个模式(规则)的文本(许多程序设计语言都支持利用正则表达式进行字符串操作)

为何要用正则表达式?
正则表达式能够帮我们更好的定位文件中的内容,从而实现对其的增删改查等操作

如何用正则表达式?
正则表达式元字符: 由各种执行模式匹配操作的程序来解析,比如vi、grep、sed、awk
提到正则表达式就不得不提元字符,正则表达式是由命令解释执行的,元字符是由shell解释器解释执行的。元字符:是一类可以表达出超越其字面本身含义的特殊字符

shell元字符(也称为通配符): 由shell解释器来解析,如rm -rf *.pdf,元字符*Shell将其解析为任意多个字符
正则表达式元字符		 : 由各种执行模式匹配操作的程序来解析,比如vi、grep、sed、awk

例如:vim示例:
:1,$ s/tom/EGON/g		 # 如anatomy、tomatoes及tomorrow中的“tom”被替换了,而Tom确没被替换
:1,$ s/\\<[Tt]om\\>/EGON/g

2.正则表达式元字符

2.1 基本正则元字符集

 元字符			功能										  示例	
^ 			  行首										^love
$ 			  行尾										 love$
. 			  除了换行符以外的任意单个字符					 l..e
* 			  左边字符的零个或多个	(贪婪)		   	      ab*love
.* 			  所有字符				(贪婪)				 a.*love
[] 			  字符组内的任一字符								 [lL]ove
[^] 		  对字符组内的每个字符取反(不匹配字符组内的每个字符)   [^a-z0-9]ove
^[^] 	      非字符组内的字符开头的行

[a-z] 		  小写字母
[A-Z] 		  大写字母
[a-Z] 	      小写和大写字母
[0-9] 	      数字

\\	  		 用来转义元字符 									  love\\.	
\\< 		     词首定位符 单词一般以空格或特殊字符做分隔、连续的字符组成  \\<love
\\> 			 词尾定位符										   love\\>
\\(..\\)		  匹配稍后将要使用的字符的标签	                \\(love\\)able\\1er	
                                                         :1,$ s/\\(192.168.11\\).66/\\1.50/g

x\\{m\\}			字符x重复出现m次							     e\\{3\\}
x\\{m,\\}			字符x重复出现m次以上								e\\{3,\\}						
x\\{m,n\\}		字符x重复出现m到n次								e\\{3,6\\}

示例:

# 1、^ 行首
[root@egon ~]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@egon ~]# 

# 2、$ 行尾
[root@egon ~]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
user1:x:1002:1003::/home/user1:/bin/bash
egon1:x:198:1005::/home/egon1:/bin/bash
gg:x:1004:1006::/home/gg:/bin/bash
egon:x:1005:1007::/home/egon:/bin/bash
tom:x:1006:1008::/home/tom:/bin/bash
[root@egon ~]# 


# 3、. 除了换行符以外的任意单个字符
[root@egon ~]# grep '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
[root@egon ~]# 

# 4、* 前导字符的零个或多个
[root@egon ~]# cat a.txt 
a

ab
abb
abbb
bbbbb
[root@egon ~]# grep 'ab*' a.txt 
a
ab
abb
abbb
[root@egon ~]# 

# 5、.* 所有字符=贪婪
[root@egon ~]# cat a.txt 
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac
111
222
333
[root@egon ~]# grep 'a.*c' a.txt 
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac
[root@egon ~]# 

# 5.1 .*?=》非贪婪,默认情况下,grep不支持非贪婪修饰符,但您可以使用grep -P来使用Perl语法来支持.*?
[root@egon ~]# cat a.txt 
<a href="http://www.baidu.com">"我他妈的是百度"</a>
<a href="http://www.sina.com.cn">"我特么的是新浪"</a>
[root@egon ~]# 

[root@egon ~]# grep -o 'href=".*"' a.txt  # 贪婪
href="http://www.baidu.com">"我他妈的是百度"
href="http://www.sina.com.cn">"我特么的是新浪"
[root@egon ~]# 

[root@egon ~]# grep -oP 'href=".*?"' a.txt  # 非贪婪
href="http://www.baidu.com"
href="http://www.sina.com.cn"
[root@egon ~]# 



# 6、[] 字符组内的任一字符
# 7、[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
[root@egon ~]# cat a.txt 
a1c
a2c
a33c
aAc
aZc
[root@egon ~]# grep 'a[0-9]c' a.txt
a1c
a2c
[root@egon ~]# grep 'a[^0-9]c' a.txt
aAc
aZc
[root@egon ~]# 
[root@egon ~]# grep 'a[0-9][0-9]c' a.txt
a33c
[root@egon ~]# 

# 8、^[^] 非字符组内的字符开头的行
[root@egon ~]# cat a.txt 
a1c
a2c
a33c
aAc
aZc
[root@egon ~]# grep '^[^0-9]..$' a.txt
a1c
a2c
aAc
aZc
[root@egon ~]# 

# 9、[a-z] 小写字母 略
# 10、[A-Z] 大写字母 略
# 11、[a-Z] 小写和大写字母 略
# 12、[0-9] 数字 略

# 13、\\< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
# 14、\\> 单词尾
[root@egon ~]# netstat -an |grep -w 80
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@egon ~]# netstat -an |grep  '\\<80\\>'
tcp6       0      0 :::80                   :::*                    LISTEN    
[root@egon ~]# netstat -an |grep  '\\b80\\b'
tcp6       0      0 :::80                   :::*                    LISTEN   

扩展正则元字符集

# 扩展正则元字符
+					匹配一个或多个前导字符		   [a-z]+ove	
?					匹配零个或一个前导字符		   lo?ve	
a|b					匹配a或b					love|hate
()					组字符						love(able|rs)  (egon)+
(..)(..)\\1\\2		标签匹配字符				  (love)able\\1er
x{n}			    x出现n次				    e{3}		
x{n,}			    x出现n次至无穷次			  e{3,}
x{n,m}		        x出现n次至m次			   e{3,6}

#若想使用扩展正则
grep加-E 或 egrep 或转义\\

sed 加 -r 参数 或转义

AWK 直接支持大多数扩展正则,更多支持需要加选项--posix选项

示例

# ======================grep扩展正则示例======================
[root@egon ~]# cat a.txt 
a

ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[root@egon ~]# grep 'ab{2,4}' a.txt  # 默认不支持扩展正则,所以没效果
[root@egon ~]# egrep 'ab{2,4}' a.txt 
abb
abbb
abbbb
abbbbb
[root@egon ~]# 

# ======================sed扩展正则示例======================
[root@egon ~]# sed -n '/roo?/p' /etc/passwd  # 默认不支持扩展正则?
[root@egon ~]# sed -n '/roo\\?/p' /etc/passwd  # 可以用\\转义扩展正则符号?
有结果,结果略...
[root@egon ~]# sed -rn '/roo?/p' /etc/passwd  # 也可以加-r选项
有结果,结果略...
[root@egon ~]# 

# ======================awk扩展正则示例======================
[root@egon ~]# cat a.txt 
a

ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[root@egon ~]# awk '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb
[root@egon ~]# awk --posix '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb
[root@egon ~]# 

总结

grep:				使用基本元字符集	^, $, ., *, [], [^], \\< \\>,\\(\\),\\{\\}
egrep(或grep -E):	使用扩展元字符集	?, +, { }, |, ( )
# 注:grep也可以使用扩展集中的元字符,仅需要对这些元字符前置一个反斜线

\\w	所有字母与数字,称为字符[a-zA-Z0-9]	   'l[a-zA-Z0-9]*ve'	   		'l\\w*ve'
\\W	所有字母与数字之外的字符,称为非字符	   'love[^a-zA-Z0-9]+' 	        'love\\W+'
\\b	词边界								'\\blove\\b'					  '\\<love\\>'

posix定义的字符分类

# 表达式       	  功能                              			示例
[:alnum:]     	字母与数字字符                       		[[:alnum:]]+  
[:alpha:]  		字母字符(包括大小写字母)					  [[:alpha:]]{4}
[:blank:]     	空格与制表符                         		  [[:blank:]]*
[:digit:]       	数字字母                            	[[:digit:]]?
[:lower:]      	小写字母                            		[[:lower:]]{5,}
[:upper:]      	大写字母                            		[[:upper:]]+
[:punct:]      	标点符号                            		[[:punct:]]
[:space:]      	包括换行符,回车等在内的所有空白[[:space:]]+


# 详解
[:alnum:] Alphanumeric characters.
匹配范围为 [a-zA-Z0-9]
[:alpha:] Alphabetic characters.
匹配范围为 [a-zA-Z]
[:blank:] Space or tab characters.
匹配范围为 空格和TAB键
[:cntrl:] Control characters.
匹配控制键 例如 ^M 要按 ctrl+v 再按回车 才能输出
[:digit:] Numeric characters.
匹配所有数字 [0-9]
[:graph:] Characters that are both printable and visible. (A space is print-
able, but not visible, while an a is both.)
匹配所有可见字符 但不包含空格和TAB 就是你在文本文档中按键盘上能用眼睛观察到的所有符号
[:lower:] Lower-case alphabetic characters.
小写 [a-z]
[:print:] Printable characters (characters that are not control characters.)
匹配所有可见字符 包括空格和TAB
能打印到纸上的所有符号
[:punct:] Punctuation characters (characters that are not letter, digits, con-
trol characters, or space characters).
特殊输入符号 +-=)(*&^%$#@!~`|\\"'{}[]:;?/>.<,
注意它不包含空格和TAB
这个集合不等于^[a-zA-Z0-9]
[:space:] Space characters (such as space, tab, and formfeed, to name a few).

[:upper:] Upper-case alphabetic characters.
大写 [A-Z]
[:xdigit:] Characters that are hexadecimal digits.
16进制数 [0-f]

# 使用方法:
[root@egon ~]# grep --color '[[:alnum:]]' /etc/passwd

以上是关于shell编程之正则表达式详解的主要内容,如果未能解决你的问题,请参考以下文章

Linux之Shell编程(17)--grep关键字详解演示

Linux之Shell编程(17)--grep关键字详解演示

shell编程之正则表达式基础正则表达式

Shell编程三剑客之grep

Shell正则表达式之grepsedawk实操笔记

自动化运维必须要学的Shell脚本之——正则表达式的详解