耳朵(八)——正则表达

 https://www.bbsmax.com/A/8Bz8gZ26dx/
   正则表达式就是为了处理大量的文本|字符串而定义的一套规则和方法。
   Linux中的正则表达式,常应用正则表达式的命令是grep(egrep),sed,awk。Linux下三剑客! 
   正则表达式分为两种: 基本正则表达式(BRE,basic regular expression) 
                                           扩展正则表达式(ERE,extended regular expression) 

grep:命令常用参数级作用
–color:匹配到颜色
-i 忽略字符大小写
-o 仅显示匹配的字串
-v 反向选取, 即显示不匹配的行
-E 使用扩展正则表达式
-n 显示行号
正则表达式常用表示方法。
^word :搜寻word开头的行 。 搜寻以#开头的行,grep -n ‘^#’ file
word$ :搜寻word结尾的行。 搜寻以.结尾的行,grep -n ‘.$’ file
.: 匹配任意一个字符。 匹配e和e之间有任意一个字符,grep -n ‘e.e’ file
\ :转义字符
: 前面的一个字符重复0到多次 。 匹配gle,gogle,google,gooogle等,grep -n 'gogle’ file
[list] :匹配一系列字符中的一个
[n1-n2] :匹配一个字符范围中的一个字符 匹配数字字符,grep -n ‘[0-9]’ file
[^list]:匹配字符集以外的字符。 匹配非o字符,grep -n ‘[^o]’ file
{n1,n2} 前面的单个字符重复n1,n2次。匹配google,gooogle,grep -n ’ go{2,3}gle ’ file
<word 单词的开头。匹配以g开头的单词,grep -n <g file
‘ ‘ 强引用,引号内的内容不变
“ ” 弱引用,变量会替换
[[:alnum:]] 代表英文大小写字符及数字,即 0-9, A-Z, a-z
[[:alpha:]] 代表任何英文大小写字符,即 A-Z, a-z
[[:space:]] 任何会产生空白的字符,包括空白键, [Tab] 等等
[[:digit:]] 代表数字,即 0-9
[[:lower:]] 代表小写字符,即 a-z
[[:upper:]] 代表大写字符,即 A-Z
#1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
cat /proc/meminfo | grep “(s|S)”
cat /proc/meminfo | grep -i “s”
#2、显示/etc/passwd文件中不以/bin/bash结尾的行
cat /etc/passwd | grep -v “/bin/bash”
#3、显示用户root默认的shell程序
[root@localhost ff]# cat /etc/passwd | grep -w “^root” | cut -d: -f 7
/bin/bash
#4、找出/etc/passwd中的两位或三位数
在这里插入图片描述 #5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
在这里插入图片描述
#7、显示CentOS7上所有系统用户的用户名和UID
在这里插入图片描述 #8、找出/etc/passwd用户名 和shell同名的行
在这里插入图片描述
#9、利用df和grep,取出磁盘各分区利用率,并从大到小排序
在这里插入图片描述
#11、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
在这里插入图片描述

#12、使用egrep取出/etc/rc.d/init.d/functions中其基名
在这里插入图片描述
#13、使用egrep取出上面路径的目录名
在这里插入图片描述
#14、统计last命令中以root登录的每个主机IP地址登录次数
在这里插入图片描述

egrep:
grep一般情况下支持基本正则表达式,可以通过参数-E支持扩展正则表达式,另外grep单独提供了一个扩展 命令叫做egrep用来支持扩展正则表达式,这条命令和grep -E等价(grep -E == egrep) 一般情况下,基本正则表达式就够用了 特殊情况下,复杂的扩展表达式,可以简化字符串的匹配 扩展正则表达式就是在基本正则表达式的基础上,增加了一些元数据

+: 重复前面字符1到多次
匹配god,good,goood等字符串,grep -nE go+d’ file
?: 匹配0或1次前面的字符
匹配gd,god,grep -nE ‘go?d’ file
| 或or的方式匹配多个字符串
匹配god或者good,grep -nE’god|good’ file
(): 匹配整个括号内的字符串,原来都是匹配单个字符
搜索good或者glad,grep -nE ‘g(oo|la)’ file
*: 前面的字符重复0到多次

重点:正则表达匹配ip地址

ip地址格式一般为xxx.xxx.xxx.xxx 如(192.168.55.1)
1、匹配ip地址的思路就是先匹配出前三个字段,在匹配第四个字段
2、拆分来看如何匹配前三个字段(192.168.55)
(1)利用数学角度考虑第一个字段192的范围:个位属于0-9;十位属于10-99;百位属于100-199
(2)因此转换成计算机的角度个位就属于[0-9]
(3)十位就属于[1-9][0-9]
(4)主要是注意百位上匹配,ip地址的数字范围本就在0-255之间因此匹配百位上的数不能用数学范围去匹配。因此匹配百位数时要考虑全面。
1、假设百位数是1那么匹配的范围就在[100-199]之间,暨:1[0-9][0-9]或者1[0-9]{2}
2、假设百位数是2那么又会分为两种情况;[200-249]和[250-255]之间,暨:2[0-4][0-9]或者25[0-5]
(5)因此一个字段的匹配就是:(([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]) )
(6)因此前三个字段的匹配就是((([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]) )[.]){3}
3、第四字段与前三字段的匹配思路一致因此ip地址的正则匹配就是:
((([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]) )[.]){3}(([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))

sed命令
与grep相似有不同,grep命令用来查询字符串时十分方便,但如果是在处理文本内容时grep命令就会显得力不从心。此时就用该用到sed命令。
sed是一种非交互式的流编辑器,可动态编辑文件;流编辑器则会在编辑器处理数据之前基于预先提供的一组 规则来编辑数据流 sed本身是一个管道命令,可以分析 standard input 的,主要是用来分析关键字的使用、统计等,此外还可 以将数据进行替换、删除、选中、选取特定行等功能。
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!
e:多次命令,sed在执行命令是可以一次性想执行多个命令。
n:sed会默认打印处理过的所有文本,-n则只打印处理的行部分。
r: 支持扩展正则表达式。
g:全局

截取一部分/etc/passwd里的内容当作测试文本,存放在t.txt文档中
[root@centos ~]# cat t.txt
root❌0:0:root:/root:/bin/bash
bin❌1:1:bin:/bin:/sbin/nologin
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin

在测试文本第二行后添加一个test字符串
[root@centos ~]# sed ‘2atest’ t.txt
root❌0:0:root:/root:/bin/bash
bin❌1:1:bin:/bin:/sbin/nologin
/test/
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin

在测试文本第二行之前添加test字符串
[root@centos ~]# sed ‘2itest’ t.txt
root❌0:0:root:/root:/bin/bash
test
bin❌1:1:bin:/bin:/sbin/nologin
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin

将文本第二三行的内容替换成test字符串
[root@centos ~]# sed ‘2,3ctest’ t.txt
root❌0:0:root:/root:/bin/bash
test
adm❌3:4:adm:/var/adm:/sbin/nologin

删除第一行的内容
[root@centos ~]# sed ‘1d’ t.txt
bin❌1:1:bin:/bin:/sbin/nologin
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin

在第一行后面添加one字符,在第二行前面添加two字符
[root@centos ~]# sed -e ‘1a one’ -e ‘2i tow’ t.txt
root❌0:0:root:/root:/bin/bash
one
two
bin❌1:1:bin:/bin:/sbin/nologin

与c参数不同,s参数常常用于正则表达,比如用sed匹配ip地址
[root@centos ~]# ifconfig | grep ‘inet’
inet 192.168.224.129 netmask 255.255.255.0 broadcast 192.168.224.255
inet6 fe80::20c:29ff:fef1:b2ba prefixlen 64 scopeid 0x20
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
[root@centos ~]# ifconfig | grep ‘inet’ | grep -v ‘inet6’
inet 192.168.224.129 netmask 255.255.255.0 broadcast 192.168.224.255
inet 127.0.0.1 netmask 255.0.0.0
[root@centos ~]# ifconfig | grep ‘inet’ | grep -v ‘inet6’ | sed ‘s/^.*inet//g’
192.168.224.129 netmask 255.255.255.0 broadcast 192.168.224.255
127.0.0.1 netmask 255.0.0.0
[root@centos ~]# ifconfig | grep ‘inet’ | grep -v ‘inet6’ | sed ‘s/^.inet//g’ | sed 's/netmask.KaTeX parse error: Expected 'EOF', got '#' at position 53: …[root@centos ~]#̲ ifconfig | sed…//’
192.168.224.129
127.0.0.1

awk
相比较与SED常常作用于一整行处理,awk则比较倾向于将一行分成数个字段处理
awk相当时候处理小型数据。
一个awk脚本通常由BEGIN, 通用语句块,END语句块组成,三部分都是可选的。 脚本通常是被单引号或双引号包住。
awk ‘BEGIN{ commands } pattern{ commands } END{ commands }’ file
awk在执行时命令参数$1,$2,指代第一个域第二个域

第一步: 执行BEGIN { commands } pattern 语句块中的语句
BEGIN语句块:在awk开始从输入输出流中读取行之前执行,在BEGIN语句块中执行如变量初始化,打印输出表头等操作。
第二步:从文件或标准输入中读取一行,然后执行pattern{ commands }语句块。它逐行扫描文件,从第一行到 最后一行重复这个过程,直到全部文件都被读取完毕。
pattern语句块:pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行。{ }类似一个循环体,会对文件中的每一行进行迭代,通常将变量初始化语句放在BEGIN语句块中,将打印结果等语句放在END语句块中。
第三步:当读至输入流末尾时,执行END { command }语句块
END语句块:在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

源文件段:
[root@localhost ~]# cat /etc/passwd | tail -n3
postfix❌89:89::/var/spool/postfix:/sbin/nologin
sshd❌74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony❌998:996::/var/lib/chrony:/sbin/nologin

对比BEGIN、PATTERN、END语段:以冒号分割截取第一列
[root@localhost ~]# cat /etc/passwd | tail -n3 | awk -F: ‘BEGIN{print “being”} {print $1}END{print"end"}’
being
postfix
sshd
chrony
end
[root@localhost ~]# cat /etc/passwd | tail -n3 | awk -F: ‘{print $1}’
postfix
sshd
chrony
注:BEGIN和END语段需要加关键字,如若不加系统默认为PATTENR语段。

awk命令参数
F:指定分割符
NF:查询域,$NF输出最后一列域
NR:输出所在行
~匹配

以冒号分割查询域
[root@localhost ~]# cat /etc/passwd | tail -n3 | awk -F: ‘{print NF}’
7
7
7
[root@localhost ~]# cat /etc/passwd | tail -n3 | awk -F: ‘{print $NF}’
/sbin/nologin
/sbin/nologin
/sbin/nologin

awk匹配ip地址
[root@localhost ~]# ifconfig ens32 | awk -F’[ :]+’ ‘NR==2 {print $3}’
192.168.17.128

[root@localhost ~]# cat /etc/passwd |awk -F: ‘gsub(/root/,“root1”) {print $0}’
root1❌0:0:root1:/root1:/bin/bash
operator❌11:0:operator:/root1:/sbin/nologin
[root@localhost ~]# cat /etc/passwd |awk -F: ‘sub(/root/,“root1”) {print $0}’
root1❌0:0:root:/root:/bin/bash
operator❌11:0:operator:/root1:/sbin/nologin
#sub匹配第一次出现的符合模式的字符串,相当于 sed ‘s//’
#gsub匹配所有的符合模式的字符串,相当于 sed ‘s//g’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值