Shell-正则表达式+三剑客

Shell正则表达式

一.什么是表达式

正则表达式(regular expression,RE)是一种 字符模式,用于在查找过程中匹配指定的字符。
在大多数程序中,正则表达式都被放在 两个正斜杠 之间;
例如:/I[oO]ve/就是正斜杠界定的正则表达式–> 表示匹配lovelOve

在正则表达式中,元字符是最重要的概念
1.Linux 正则表达式grep,sed,awk
2.大量字符串文件需要进行配置,而且是非交互式的;
3.过滤相关的字符串,匹配字符串,打印字符串。

注意事项

  • Linux正则一般以行为单位匹配处理;
  • alias grep='grep --color=auto
1.正则表达式元字符
^root 	行首定位符	查找以root开头的行
bash$	行尾定位符	查找以bash结尾的行
.		匹配单个字符  代表任意一个字符
0*		匹配前导符0到多次      匹配ro*t的o,可以有0个o,也可以有多个o
.*		任意多个字符          不管什么数字字符都匹配上
[o0]    匹配指定范围内一个字符	o和0都匹配上
[0-9]	匹配指定范围内一个字符	是数字全匹配上
[^0-9]	匹配不在指定范围内的	除了不匹配数字,其他全匹配
\		转义元字符			love\. 将点转义,否则点代表任意字符,不显示
\  词尾定位符			root\> 定位以root结尾的单词
\(..\)  匹配稍后使用的字符的标签	
-------------------
x\{m\}	字符x重复出现m次                o\{3\}  o重复出现3次
x\{m,\}	字符x重复出现m次,以上	o\{3,\}  o重复出现3次以上
x\{m,n\}	字符x重复出现m到n次         o\{5,10\) o重复出现5到10次

二.grep介绍

2.1 grep家族
grep:在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行
egrep:扩展的egrep,支持更多的正则表达式元字符
fgrep:固定grep fixed grep,字面解释所有的字符 (看到什么就是什么)
2.2 grep命令
grep [选项] '模式 filename1 filename2
返回值:
找到: grep返回状态码0
没找到: grep返回状态码1
找不到文件: grep返回状态码2
grep选项
-i,--ignore-case 忽略大小写
-n,--line-number 匹配每一行前加上相对行号
-c,--count 显示成功匹配的行数
-q,--quiet,--silent 匹配上也不回显,多用于shell脚本
-v,--invert-match 取反,只显示不匹配的行
-o,--only-matching 只显示匹配的内容
-w, 只匹配单个单词

2.3 grep实例
匹配以ro开头的行:
# grep '^ro' /etc/passwd
匹配以ot结尾的行:
# grep 'ot$' /etc/passwd
排除空行:
#grep -v '^$' /etc/nsswitch.conf
同时匹配两次^ :#grep "^[^rc]oot" /etc/passwd
- 第一个^ :表示匹配以什么开头
- 第二个^:表示排除r或c开头的词
匹配所有字符[a-zA-Z0-9]:
# grep '\w' /etc/passwd
所有字母与数字之外非字符:
# grep '\W' /etc/passwd
词边界
# grep '\broot\b' /etc/passwd \b=\< 或 \>

2.4 egrep实例
查找包含NW 或EA 的行
#egrep ’NW|EA‘ datafile
查找有一到多个3的行
#egrep ’3+‘ datafile
查找2+0到多个点+一个数字
#egrep ’2\.?[0-9]‘ datafile
查找一个或多个no
#egrep ’(no)+' datafile
查找Sh 或Su的行
#egrep ‘S(h|u)' datafile
查找Sh或u 的行
#egrep ’Sh|u‘ datafile

取出ip add中的IP

最方便的方式:
# hostname -I
192.168.31.153

方式一:
# ip add | grep inet | egrep -o  "[0-9]{3}.[0-9]{1,}.[0-9]{1,}.[0-9]{1,}"
127.0.0.1
192.168.31.153
192.168.31.255
方式二:
# ip add | grep inet | egrep -o  "[0-9]{3}.[0-9]+.[0-9]+.[0-9]+"
127.0.0.1
192.168.31.153
192.168.31.255

三、sed

sed是一个流编辑器,非交互式的编辑器,一次处理一行。
处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)。
接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行

3.1 sed命令
#sed [选项] ‘模式’ filename1 filename2
sed支持对指定行进行操作,包括打印,删除,修改,追加
选项 功能
-e 允许多项编辑
-n 取消默认的输出
-i 直接修改对应内容
-r 支持扩展元字符(不需要再对符号转义)

返回值
sed和grep不一样
不管是否找到:返回值都是0
语法错误时:返回值才是非0

3.2 支持正则表达式
与grep一样,sed在文件中查找模式时也可以使用正则表达式
正则表达式是 括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符

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

使用扩展元字符的方式:
使用斜线转义\+ sed -r

3.2 sed实例
//打印命令p
相当于cat命令
#sed ' ' filename
打印第二行
#sed -n '2p' filename (-n:取消默认输入文件内容)
打印匹配到的行
# sed '/halt/p' passwd -n halt:x:7:0:halt:/sbin:/sbin/halt
打印最后一行
# sed -n '$p' passwd

//删除命令-d
删除第2行
# sed -rn '2d' passwd
#sed -r '{2d}' passwd
删除最后一行
# sed -r '$d' passwd
删除第3行到最后一行
# sed -r '3,$d' passwd
删除带有root的行(正则表达式)
# sed -r '/root/d' passwd

删除#号注释行
#sed -ri '/^[ \t]*#/d' file.conf

删除//号的注释行
# sed -ri '\#^[ \t]*//#d' test
# sed -r '/^[ \t]*\/\//d' test

删除空行
# sed -ri '/^[ \t]*$/d' test

删除注释行及空行
#sed -ri '/^[ \t]*#/d;/^[ \t]*$/d' test
#sed -r '/^[ \t]*($|#)/d' filename

//修改文件-c
#sed -ri ’/UserDNS/cUserDNS no/d‘ /etc/ssh/ssh_config
#sed -ri '$a\chroot_local=YES' /etc/vsftpd/vsftpd.conf //在最后一行添加chroot_local=YES
#sed -ri '/^SELINUX=/cSELINUX=disabled/d' /etc/selinux/config //查找SELINUX开头的行,整行替换成SELINUX=disabled

# sed -r '1,5s/^#*/#/' c.txt //将1,5行的0个到多个#,换成一个#(避免出现有一个#,再加一个#不好看)·

//给文件添加注释

# sed -r 's/^/#/' resolve 
# sed -r '1,4s/^/#/' resolve  #给1-4行添加注释
# sed -r '2,6s/.*/#&99/' passwd  在第二行到第六行最前面添加#,& 行后,添加99
	root:x:0:0:root:/root:/bin/bash
	#bin:x:1:1:bin:/bin:/sbin/nologin99
	#daemon:x:2:2:daemon:/sbin:/sbin/nologin99
	#adm:x:3:4:adm:/var/adm:/sbin/nologin99
	#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin99
	#sync:x:5:0:sync:/sbin:/bin/sync99
	shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
	halt:x:7:0:halt:/sbin:/sbin/halt


总结:
1. 打印p
2. 删除d
3. 追加a、i
4. 替换c
5. 替换sg
正则匹配替换
针对特定的行进行匹配
6. 非交互式修改文件

面试题:
假如有一个20G的文件,想编辑其中的一行。怎么办?
答:
使用sed,sed把当前处理的第一行存在模式空间中,查看是否是想编辑的该行,不是就接着处理下一行。(一行一行的读不会卡)

四、awk

awk是一个强大的文本处理工具,通常配合脚本进行使用。
awk是一种编程语言,用于Linux下对文本和数据进行处理

4.1 awk处理文本和数据的方式
  • 逐行扫面文件,从第一行到最后一行,寻找特定模式的行
语法:
#awk [选项]  (参数)

选项:
-F 定义输入字段分隔符,默认分隔符为空格或tab键
-F “:”	==>定义以 :作为分隔字段
参数:
BEGIN{}		{}			END{}
行处理前		行处理中		行处理后
BEGIN{} 通常用于定义一些变量
	FS:指定字段分隔符,跟-F 一样的效果
	OFS:

理解行处理前/中/后:

# awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}' /etc/hosts
	  |行处理前		   | 行处理中 	|行处理后
	  |0.5
					   |ok
					   |ok
									|Game Over

awk命令格式(实例介绍)

//awk 'pattern' filename ==>仅使用匹配,匹配文件
# awk  -F: '/root/' /etc/passwd

//awk '{action}' filename ==>对文件进行动作处理
#  awk -F: '{print $1}' /etc/passwd

//awk 'pattern {action}' filename ==>匹配+处理动作
# awk -F: '/root/{print$1,$3}' passwd
# awk 'BEGIN{FS=":"} /root/{print $1,$3}' passwd 

//判断条件输出内容,判断已用大于1G,打印出挂载点下的可用容量
文件系统                   容量  已用   可用  已用% 挂载点
/dev/mapper/centos-root   18G  1.4G   17G    8% /
devtmpfs                 479M     0  479M    0% /dev

# df -h | awk '/\/$/ {if ($3>1) print $4}' 
17G
4.2 awk工作原理

如下命令awk -F: '{print $1,$3}' passwd工作原理

# awk -F: '{print $1,$3}' passwd   
root 0
bin 1
daemon 2
adm 3

  1. awk读一行,并将此行赋值给$0,每一行也可称为一个记录,以换行符结束;
  2. awk进行字段分解,每个字段存储在已编号的变量中,从$1开始;
  3. awk默认是的分隔符是 空格,有内部变量FS决定;
  4. awk打印字段,将以设置的方法使用print函数打印;
  5. awk在打印的字段间加上空格,因为是$1,$3之间有个,逗号,逗号映射成另一个内部连梁OFS默认是空格(,=OFS=空格);
  6. awk输出后,将从文件中读取另一行,并存储在$0中,覆盖上一行内容。重新将字符串分隔成字段;
4.3 awk的内部变量
//$0:awk变量$0读取当前行的内容
# awk -F: '{print $0}' passwd  

//NR:控制输出的行数,打印前三行 (支持大于、小于、等于)
# awk 'NR<=3{print $0}' passwd
//FNR:记录输入文件的编号,不同文件不连续编号。
# awk '{print FNR,$0}' passwd /etc/hosts

//NF:打印保存行的最后一列的内容
# awk -F: '{print $1,$NF}'  passwd 
root /bin/bash

//FS:指定字段分隔符,默认空格
# awk  -F 'NR==2{print $1,$2}'  /etc/resolv.conf
///指定多个分隔符,以空格冒号tab作为字段分隔
# awk -F'[ :\t]' '{print $1,$3,$4}' passwd

//OFS:自定义输出字段分隔符,默认是空格,修改方式如下
	# awk -F:  '/root/{print $1,$2,$3}' passwd root x 0
	operator x 11
	# awk 'BEGIN{FS=":"; OFS="++"} /root/{print $1,$2}' passwd 
	root++x
	operator++x


更多更好的原创文章,请访问官方网站: 点我就能跳转咯-》https://nothingzh.gitee.io
也可关注“哎呦运维”微信订阅号,随时接受文章推送。

你可能感兴趣的:(Shell编程,linux,正则表达式,shell)