Linux Shell脚本之正则表达式

举报
jiangxl 发表于 2022/05/09 00:56:51 2022/05/09
【摘要】 正则表达式RE 重要的文本处理工具:vim sed awk grep 1.什么是正则表达式? 正则表达式(regular expression,RE)是一种字符模式,用于在查找过程中匹配指定的字符。...

正则表达式RE

重要的文本处理工具:vim sed awk grep

1.什么是正则表达式?

正则表达式(regular expression,RE)是一种字符模式,用于在查找过程中匹配指定的字符。

在大多数程序里,正则表达式都被置于两个斜杠之间;例如/l[oO]ve/就是由正斜杠界定的正则表达式。

它将匹配被查找的行中任何位置出现的相同模式,在正则表达式中,元字符是重要的概念

匹配数字:1+$ ^:以xxx开头,+前面的对象出现一个或多个,$是以xxx结尾,[]里面的是匹配的模式

匹配mail:[a-z0-9_]+@[a-z0-9]+\.[a-z]+

  
 
  • 1
匹配ip:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}

  
 
  • 1
  • 2
  • 3
[root@localhost ~]# egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.81.250
NETMASK=255.255.255.0
GATEWAY=192.168.81.2
DNS1=192.168.81.2

或:
[root@localhost ~]# egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.81.250
NETMASK=255.255.255.0
GATEWAY=192.168.81.2
DNS1=192.168.81.2


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.元字符

定义:元字符是这样一类字符,他们表达的是不同于字面本身的含义

shell元字符(也称为通配符)由shell来解析,如rm -rf *.pdf,元字符星号*shell将其解析为任意多个字符

正则表达式元字符 由各种执行模式匹配操作的程序来解析,比如vim、grep、sed、awk、python

例子:

[root@localhost d09_shell_re_zzbds]# rm -rf *.ps		表示删除所有以.ps结束的文件
[root@localhost d09_shell_re_zzbds]# grep 'c*' /etc/passwd		这个不在是shell来解析,这一点会让人误以为是c开头包含任意字符的行,其实不是,会输出所有行,这里由grep来解析,表示c出现0次或多次也就是c可以不出现,那么不匹配c的行也会出现,显然不是我们想要的,可以使用grep 'c\+' /etc/passwd来完成匹配或者egrep 'c+' /etc/passwd

  
 
  • 1
  • 2

vim实例:

:1,$ s/tom/TOM/g		这里的1,$等同于%都表示全文假如有Tom字符或者tomorrow那么也会被改变不太合理,可以使用正则
:1,$ s/\<[tT]om\>/TOM/g		这里利用词首和词尾定位符锁定只能是tom单词才会被更改

  
 
  • 1
  • 2

2.1正则表达式元字符

=基于正则表达式元字符

匹配模式中严格区分大小写

  元字符 							功能        								示例      

	^		行首定位符				grep '^root' /etc/passwd /etc/shadow

	$		行尾定位符     			grep 'bash$' /etc/passwd /etc/shadow

	.  		匹配单个字符    			grep 'r.t' /etc/passwd   grep '^r..t' /etc/passwd 

	*   	匹配前导符0次或多次		  grep 'ro*t' /etc/passwd

	.*		任意多个字符				grep 'r.*t' /etc/passwd

	[]		匹配指定范围内的一个字符	grep '[rR]oot' /etc/passwd

	[ - ]	匹配指定范围内的一个字符	grep'[a-z0-9]oot' /etc/passwd,如果要去大小写a-z的话可以这么写[a-zA-Z]或者[a-Z]

	[ ^ ]	匹配不在指定组内的字符		grep '[^a-z0-9]oot' /etc/passwd 过滤不包含a-z0-9的oot的字符
	\		用来转义元字符			   grep 'love\.' love.txt
	\<		词首定位符				grep '\<root' /etc/passwd
    \>		词尾定位符				grep 'root\>' /etc/passwd
    \(..\)	匹配稍后使用的字符的标签只适用于替换,在bash不支持   %s /(\192.168.81.\)250/\1251/g
    x\{m\}	字符x重复出现m次			grep 'o\{5\}' /etc/passwd
    x\{m,\}	字符x重复出现m次以上		   grep 'o\{5,\}' /etc/passwd
    x\{m,n\}	字符x重复出现m到n次		grep 'o{2,5\}' /etc/passwd
	
	==================================几个例子==================================
grep '\<root\>' /etc/passwd             //限制词首和词尾都是root的单词
grep '^\<root\>' /etc/passwd            //仅是以root单词开头的行

%s/192.168.81.250/192.168.81.251/g              //正常情况在vim中要改一个字符
%s/\(192.168.81.\)250/\1251/g                   //利用正则\(..\)来改,这种情况在:如果要改的字符前一部分跟之前一样,可以使用\(\)在括号中把相同的部分在括号中写好,然后>在使用\1调用第一个括号中的内容,如果是定义了两个括号就使用\2调用第二个括号中的内容
%s#\(192.168.81\).250#\1.251#g                  //这个原理和上调命令一致,#等同于/
%s#\(192.\)\(168.\)\(81.\)250#\1\2\3251#g               //多括号
%s/\(192\).\(168\).\(81\).250/\1.\2.\3.251/g
3,8 s/\(.*\)/#\1                        //3-8行在每行前面加一个#

egrep 'ro*' /etc/passwd //匹配o出现0或多次
egrep 'ro{2}' /etc/passwd       //匹配o出现2次
egrep 'ro{2,}' /etc/passwd      //匹配o出现2次以上
egrep 'ro{2,5}' /etc/passwd     //匹配o出现两次到五次

grep 'ro*' /etc/passwd  //匹配o出现0或多次
grep 'ro\{2\}' /etc/passwd      //匹配o出现2次
grep 'ro\{2,\}' /etc/passwd     //匹配o出现2次以上
grep 'ro\{2,5\}' /etc/passwd    //匹配o出现两次到五次   

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2.2扩展正则表达式元字符

扩展元字符的意思和基础的一致,就是省略了一些特殊符号用egrep来进行匹配

+		匹配一个或多个前导字符		[a-z]+ove
?		匹配0个或1个前导字符		  lo?ve
a|b		匹配a或b				love|hate
()		组字符					loveable|rs	love(able|rs)ov+ ov+(ov)+	组字符也就是匹配括号中的内容,ov+是v一个或多个,(ov)+是ov两个字符一个或多个
    (..)(..)\1\2	标签匹配字符		(love)able\1er和基础元字符一样
x{m}	字符x重复m次		o{5}
x{m,}	字符x重复至少m次	o{5,}
x{m,n}	字符x重复m到n次	o{5,10}
=========================例子========================
egrep 'ro+t' /etc/passwd        //o出现1次或多次
egrep 'ro?t' /etc/passwd        //o出现0次或1次
egrep 'root|jxl' /etc/passwd    //匹配root或者jxl的行
netstat -lnpt -an | egrep ':80|:22\>'   //匹配80或者22号端口
egrep 'ro(ot|or)' /etc/passwd           //组字符,匹配ot或者or
egrep 'r(o)+t' /etc/passwd              //组字符o出现多次


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.3.POSIX字符类

这种类型类似于系统的环境变量,由系统定义好的,我们来用就行

表达式					功能							实例

[:alnum:]			字母与数字字符					[[:alnum:]]+	//字母和数字出现多次

[:alpha:]			字母字符(包括大小写字母)		[[:alpha:]]{4}		//字母字符出现四次

[:blank:]			空格与制表符					 [[:blank:]]*	//出现0次到多次

[:digit:]			数字字母					  [[:digit:]]?	//出现0次或1次

[:lower:]			小写字母				      [[:lower:]]{5,}		//出现5次以上

[:upper:]			大写字母				      [[:upper:]]+		//出现一次或多次

[:punct:]			标点符号				      [[:punct:]]

[:space:]			包括换行符,回车等在内的所有空白  [[:space:]]+


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.正则匹配实例:vim

/love/				//匹配love的行
/^love/			//以love开头的行
/love$/			//以love结尾的行
/l.ve/				//l后面任意一个字符ove的行
/lo*ve/			//o可以出现0次到多次
/[Ll]ove/			//L或者l任意其中一个
/love[a-z]/		//love后面跟一个a-z字符的行
/love[^a-zA-Z0-9]			//除去a-zA-Z0-9的行


/.*/			//任意多个字符表示一行
/^$/			//空行,有一个回车
/^[A-Z]..$/			//以大写A-Z开头再跟后面有两个字符的行
/^[A-Z][a-z]*3[0-5]/		//以大写字母A-Z开头在跟a-z出现0次或多次再跟3在跟一个0-5的数字
/[a-z]*\./			//a-z出现0次到多次后面在跟个点
/^ *[A-Z][a-z][a-z]$/	//以0个到多个空行开头在跟一个包含A-Z的在跟一个包含在跟一个a-z的包含a-z结尾的行
/^[A-Za-z]*[^,][A_Za-z]*$/		//以A-Z或者a-z开头0个到多个在跟一个非逗号在跟一个A-Z或a-z0到多个结尾的
/\<fourth\>			//匹配一个单词
/\<f.*th/>			//匹配一个f开头th结尾的单词
\5{2}2{3}\./ 		//5出现2次,2出现3次在跟一个点


空行
/^$/		//空行
/^[ \t]*$/		//0到多个空格或tab键开头或结尾的


注释行
/^#/	//#开头的行
/^[ \t]*#/		//以空格或tab键开头的0到多个在跟一个#

:1,$/\([Oo]ccur\)ence/\1rence/		//全文搜索O或者occurence的行找到后利用标签\1调用第一个括号后面在跟上rence
:1,$/(square\)and\(fair\)/\2 and \1/		//就是将第二个标签的内容与第一个标签的内容换了个位置

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

  1. 0-9 ↩︎

文章来源: jiangxl.blog.csdn.net,作者:Jiangxl~,版权归原作者所有,如需转载,请联系作者。

原文链接:jiangxl.blog.csdn.net/article/details/124643445

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。