shell编程-常用的正则表达式

1.常用元字符

^   行首定位符            	    ^love
$   行尾定位符			 	   love$
.   任意单个字符				   l..e
*   前导符0到n次          	    ab*love
.*  任意多个字符
[]  匹配指定范围内一个字符  	    [lL]  
[-] 匹配指定范围内一个字符 	    [a-z0-9]ove
[^] 匹配不在组内的字符	  	     [^a-z0-9]ove
\   转义字符				    	love\.
\<  词首定位符			 	    \<love
\>  词尾定位符			  	    love\>
\(..\)   匹配稍后使用的字符标签   :%s/192.168.211.1/192.168.211.5/
							     :%s/\(192.168.211.\)1/\15/
							     :%s/\(192.\)\(168.\)\(211.\)1/\1\2\33/
							     :%3,9s/\(.*)/#\1/
x\{m\}   字符x重复出现m次         o\{5\}
x\{m,\}  字符x重复出现m次以上      o\{5,\}
x\{m,n\} 字符x重复出现m-n次       o\{5,10\}

拓展
+     匹配一个或多个前导字符       [a-z]+love
?    匹配零个或多个前导字符       lo?ve
a|b   匹配a或b				     love|hate
()    组字符					  
(..)(..)\1\2   标签匹配字符      (love)able\1er
x{m}  字符x重复m次               a{2}
x{m,} 字符x重复至少m次            b{3,}  
x{m,n} 字符x重复m到n次           c{1,5}

2.shell编程-grep家族

grep: 在文件中全局查找指定的正则表达式,并打印该表达式所有的行  
egrep: grep的拓展,支持更多的正则表达式元字符
fgrep: 固定grep,按字面解释所有的字符

grep [选项] PATTERN filename filename ...
#grep 'hello world' /tmp/test
找到             grep返回的退出状态为0
找不到			  grep返回的退出状态为0
找不到指定文件     grep返回的退出状态为0

grep使用的元字符

grep:    使用的基本元字符集 ^,$,.,*,[],[^],\<\>,\(\),\{\}
egrep(grep -E):使用的基本元字符集 ?,+,{},|,()

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

grep选项

-i           --ignore-case  	忽略大小写
-l	         --files-with-matches	只列出匹配行所在文件名
-n	         --line-number	在每一行前面加上它的文件中的相对好
-c 			 --count	显示成功匹配的行数
-s			 --no-messages	禁止显示文件不存在或文件不可读的错误信息
-q			 --quiet,--silent	静默
-V			 --invert-match	反向查找,只显示不匹配的行
-R,-r		 --recursive	递归针对目录
-color      颜色
-O			 --only-matching	只显示匹配内容
-B			 --before-context=NUM   print NUM lines of leading context
-A			 --after-context=NUM    print NUM lines of trailing context
-C			 --context=NUM	        print NUM lines of output context

3.shell编程流编辑器sed

非交互式编辑器,一次处理一行内容

sed主要用来自动编辑一个或多个 文件,简化对文件的反复操作,编写转换程序等

sed  -ri.bak  (i比较危险,一般加上.bak)
sed  -ric  --follow-symlinks

命名格式

sed  [options]  'command'  file(s)   主要用这个
sed  [options]  -f  scriptfile  file(s)

sed和grep不同,无论是否找到指定的模式,它的退出状态都是0,只有当语法存在错误时候,sed的退出状态才是非0

sed "参数"  '模式'
参数  1 -f 指定一个规则文件 2 -n 阻止输入行输出 -r 扩展正则
模式  1 s 替换  2 g 整行 3 d 删除 4 p 打印

支持正则表达式

使用基本元字符集  ^,$,.,*,[],[^],\<\>,\(\),\{\}
使用拓展元字符集  ?,+,{},|,()

使用拓展元字符方式:
\+
sed -r

sed命令

sed命令告诉sed对指定进行何种操作,包括打印、删除、修改等。

命令			功能
a			 在当前行后添加一行或多行
c			 用新文本修改(替换)当前行中的文本
d			 删除行
l			 列出非打印字符
i			 在当前行之前插入文本
p			 打印行
n			 读入下一行,并从下一行命令而不是第一条命令开始对其处理
q			 结束或退出sed
!			 对所选行以外的所有行应用命令

写文件命令:w

#sed -r '/north/w newfile' datafile
#sed -r '3,$w /new1.txt' datafile

追加命令:a

#sed -r '2a\1111111111'  /etc/hosts
#sed -r '2a\11111111111\
>22222222222\
>333333333333'  /etc/hosts

插入命令:i

#sed -r '2i\11111111111' /etc/hosts
#sed -r '2i111111111\
2222222\
333333333' /etc/hosts

修改命令:c

#sed -r '2c\111111111' /etc/hosts
#sed -r '2c\11111111\
>2222222222\
3333333333'  /etc/hosts 

获取下一行命令:n

#sed -r '/eastern/{ n;d }' datafile
#sed -r '/eastern/{ n;s/AM/Archile }' datafile 

暂存和取用命令:h H g G

#sed -r '1h;$G'        /etc/hosts
#sed -r '1{h;d};$G'   /etc/hosts
#sed -r '1h;2,$g'      /etc/hosts
#sed -r '1h;2,3H;$G'  /etc/hosts

暂存空间和模式空间互换命令:x

#sed -r '4h;5x;6G' /etc/hosts

反向选择:!

#sed -r '3d' /etc/hosts
#sed -r '3!d' /etc/hosts

多重编辑选项:e

#sed -r -e '1,3d' -e 's/Hememway/Jones' datafile
#sed -r '1,3d; s/Hememway/Jones'  datafile

#sed -r '2s/WE/1000phone/g; 2s/Gray/YYY/g' datafile
#sed -r '2s{s/WE/1000phone/g; s/Gray/YYY/g}' datafile
sed常见操作
删除配置文件中#号注释行
sed -ri '/^[ \t]*#/d' file.conf
删除配置文件中//号注释行
sed -ri '\Y^[ \t]*//Yd' file.conf
删除无内容空行
sed -ri '/^[ \t]*$/d' file.conf

4.shell编程-awk

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk处理过程: 依次对每一行进行处理,然后输出 默认分隔符是空格或者tab键

BEGIN{} {}
行处理前
END{}
行处理 行处理后
[root@newrain ~]# awk 'BEGIN{print 1/2} {print "ok"} END{print "----"}' /etc/hosts 
0.5
ok
ok
ok
ok 
ok
ok
----

awk工作原理
awk -F":" '{print $1,$3}' /etc/passwd 
(1)awk使用一行作为输入,并将这一行赋给变量$0,每一行可称作为一个记录,以换行符结束
(2)然后,行被:分解成字段,每个字段存储在已编号的变量中,从$1开始 
(3)awk如何知道空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符,初始时,FS赋为空格或者是tab 
(4)awk打印字段时,将以设置的方法,使用print函数打印,awk在打印的字段间加上空格,因为$1,$3间有一个,逗号。逗 号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格 
(5)awk打印字段时,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处 理。该过程持续到处理文件结束。


默认分隔符是空格或者tab键
awk中的特殊变量:
常用:
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号 
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
难理解:
FS(输入字段分隔符) 
OFS(输出字段分隔符) 
NR(Number of record)行数 
FNR按不同的文件分开 
RS(输入记录分隔符) 
ORS(输出记录分隔符)
NF 字段个数
S

FS(输入字段分隔符) (filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
OFS(输出字段分隔符)        (output filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":";OFS=".."} {print $1,$2}' /etc/passwd 
root..x
bin..x 
daemon..x 
adm..x 
lp..x 
sync..x 
shutdown..x

NR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号 
[root@newrain ~]# awk -F: '{print NR,$0}' a.txt file1.txt 
1 love
2 love.
3 loove
4 looooove
5
6 isuo
7 IPADDR=192.168.6.5
8 hjahj123
9 GATEWAY=192.168.1.1
10 NETMASK=255.255.255.0
11 DNS=114.114.114.114

FNR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号(不同文件分开) 
[root@newrain ~]# awk -F: '{print FNR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
5
1 isuo
2 IPADDR=192.168.6.5 
3 hjahj123
4 GATEWAY=192.168.1.1
5 NETMASK=255.255.255.0
6 DNS=114.114.114.114

RS(输入记录分隔符)
[root@newrain ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# awk -F: 'BEGIN{RS="bash"} {print $0}' passwd
root:x:0:0:root:/root:/bin/

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

ORS(输出记录分隔符)
[root@newrain ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash 
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' passwd
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin  daemon:x:2:2:daemon:/sbin:/sbin/nologin

格式化输出
print函数
#date |awk '{print "Month:"$2"\nYear:"$NF}'
#awk -F":" '{print "username is: "$1"\1 uid is:"$3 }' /etc/passwd
#awk -F":" '{print "\tusername and  uid:" $1,$3"!"} /etc/passwd

printf函数
#awk -F":" '{printf "%-15s %-10s %-15s\n",$1,$2,$3}' /etc/passwd
#awk -F":" '{printf "|%-15s |%-10s |%-15s\n",$1,$2,$3}' /etc/passwd

%s 字符类型
%d 数值类型
占15字符
- 表示左对齐,默认是右对齐
printf默认不会在行尾自动换行,加\n

任何awk语句都是由模式和动作组成,模式部分决定动作语句何时触发事件。处理就是对数据进行操作。如果省略模式部分,动作将时刻保持执行状态。模式可以是任何条件语句或复合语句或正则语句。模式包括两个特殊字段BEGIN和END。

==正则表达式
匹配记录(整行):
#awk '/^alice/' /etc/passwd
#awk '$0 ~ /^alice/' /etc/passwd
#awk '!/alice/' passwd
#awk '$0 !~ /^alice/' /etc/passwd

匹配字段:匹配操作符(~ !~)
#awk -F":" '$1 ~ /^alice/' /etc/passwd
#awk -F":" '$NF !~ /bash$/' /etc/passwd

==比较表达式
比较表达式采用对文本进行比较,只有条件为真时,才执行指定动作。比较表达式使用关系运算符,用于比较数字和字符串。

关系运算符
运算符				含义			
<				  小于
<=				  小于等于
==				  等于
!=				  不等于
>=				  大于等于
>				  大于

#awk -F ":" '$3 == 0' /etc/passwd
#awk -F ":" '$3 < 10' /etc/passwd
#awk -F ":" '$7 == "/bin/bash"' /etc/passwd
#awk -F ":" '$1 =="root"' /etc/passwd
#awk -F ":" '$1 ~ /roo/' /etc/passwd
#awk -F ":" '$1 !~ /root/' /etc/passwd
#df -P |grep "/" |awk '$4 > 25000'

==条件表达式:
#awk -F":" '$3>300 {print $0}' /etc/passewd
#awk -F":" '{ if($3>300) print $0 }' /etc/passewd
#awk -F":" '{ if($3>300) {print $0} }' /etc/passewd
#awk -F":" '{ if($3>300) {print $3} else{print $1} }' /etc/passewd

==算数表达式
#awk -F":" '$3 * 10 > 500' /etc/passewd
#awk -F":" '{ if($3*10>500) {print $0} }' /etc/passewd

==逻辑操作符和复合模式
&&		逻辑与		a&&b
||		逻辑或		a||b
! 		逻辑非		!a
#awk -F":" '$1~/root/ && $3<=15'  /etc/passwd
#awk -F":" '$1~/root/ || $3<=15'  /etc/passwd
#awk -F":" '!($1~/root/ || $3<=15)'  /etc/passwd

==范围模式
#awk '/Tom/,/Suzanne'  filename

==条件判断
if语句:
{if(表达式){语句;语句;...}}
if...else语句:
{if(表达式){语句;语句;...} else(表达式){语句;语句;...}}
if..else if..else语句:
{if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else{语句;语句;...}}

		逻辑或		a||b
! 		逻辑非		!a
#awk -F":" '$1~/root/ && $3<=15'  /etc/passwd
#awk -F":" '$1~/root/ || $3<=15'  /etc/passwd
#awk -F":" '!($1~/root/ || $3<=15)'  /etc/passwd

==范围模式
#awk '/Tom/,/Suzanne'  filename

==条件判断
if语句:
{if(表达式){语句;语句;...}}
if...else语句:
{if(表达式){语句;语句;...} else(表达式){语句;语句;...}}
if..else if..else语句:
{if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else{语句;语句;...}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值