Shell之正则表达式

10 篇文章 0 订阅

1、通配符

通配符指通用的,并且运用在模糊查询的场景中的字符

1.1、*与?的区别

  • *代表0个或者多个字符

  • ?代表有且只有一个任意字符

2、正则表达式

  • 匹配的精确度比通配符更高,也是运用在模糊查询的场景中

  • 通常用于判断语句中,用来检查某一字符串是否满足某一格式

2.1、正则表达式的组成

正则表达式是由普通字符与元字符组成的

  • 普通字符包括大小写字母、数字、标点符号及一些其他符号

  • 元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符或者表达式)在目标对象的出现模式

2.2、常见元字符

支持的工具:grep、egrep、sed、awk

元字符解释
\用于取消特殊符号的含义,例如:\! \n \$ 等
^匹配字符串结束的位置,例; ^a ^the ^# ^[a-z]
$匹配字符串结束的位置,例:word$ ^$匹配空行
.匹配除\n之外的任意一个字符,例:go.d g....d
*匹配前面子表达式0次或者多次,例goo.*d go.*d
[list]匹配list列表的一个字符,例如go[ola]d,[abc] [a-z] [a-z0-9] [0-9]匹配任意数字
[^list]匹配任意非list列表中的前一个字符,例如[^0-9] [^A-Z0-9] [^a-z]匹配任意一位非小写字母
\{n\}匹配前面的子表达式n次,
\{n,\}匹配前面的子表达式不少于n次
\{n,m\}匹配前面的子表达式n到m次

注意:egrep、awk使用{n} {n,} {n,m}匹配时”{}“前不用加”\“

  • \w 匹配包括下划线的任意单词字符 \W 匹配任意非单词字符 等价于 ”[^A-Za-z0-9]“

  • \d 匹配一个数字字符 \D 匹配一个非数字字符 等价于 [^0-9]

  • \s 空白符 \S非空白符

go\{,3\}d  相当于  go\{0,3\}d

2.3、扩展元字符

支持的工具egrep 、awk、grep -E 、sed -r

  • + 匹配前面子表达式1次以上 ,例 go+d , 将匹配至少一个o,如god、good

  • ? 匹配前面子表达式0次或者一次, 例如;go?d 将匹配gd或god

  • () 将括号中的字符串作为一个整体 , 例g(oo)+d 将匹配oo整体一次以上,如good,goood等

  • | 以或的方式匹配字条串 例: g(oo|la) 将匹配good或者glad

egrep "go+d"  文件名  
至少是god
-----------------------
egrep  "go?d"  文件名
匹配gd 或god
----------------------
egrep  "g(oo)+d"  文件名
匹配good   gooood    oo为整体

示例:匹配南京电信的号码

025 5XXXXXXX
025 8XXXXXXX
025-
025XXXXXXXXX
------------------------------
区号  ^025
连接符 [- ]?
号码  [58][0-9]{7}$
-------------------------------
grep  "^025[- ]?[58][0-9]{7}$"   

3、sed编辑器

  • sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流

  • sed编辑器是可以根据命令来处理数据流中的数据,这些数据要么从命令行中输入,要么存储在一个命令文本文件中

3.1、工作流程

工作流程主要包括读取、执行和显示三个过程

  • 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)

  • 执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令

  • 显示:发送修改后的内容到输入流。在发送数据后,模式空间将会被清空。在所有的文件内容中都被处理完成

在所有的文件内容都被处理完成之前,上述过程将重复执行,直到所有内容被处理完
----------------------------------------------------------------
注意:
默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发送任何改变,除非是重定向输出或sed -i

3.2、命令格式

sed -e '操作'  文件1  文件2 ....
sed -n -e '操作'  文件1  文件2 ....   -n不显示到屏幕当中
sed -f  脚本文件  文件1  文件2.....
sed -i -e '操作'  文件1   文件2 ....
sed -e 'n{
操作1
操作2
....
}'   文件1   文件2  ....

3.3、常用选项

选项解释
-e或--expression=表示用指定命令来处理输入的文本文件,只由一个操作命令时可省略,一般在执行多个操作命令使用
-f或--file=表示用指定的脚本文件来处理输入的文本文件
-h或--help显示帮助
-n、--quiet或silent禁止sed编辑器输出,但可以与p命令一起使用完成输出
-i直接修改目标文本文件

3.4、常用操作

s:替换,替换指定字符
d:删除,删除选定的行
a:增加,在当前行下面增加一行指定内容
i:插入,在选定行替换为指定内容
c:替换,将选定行替换为指定内容
y:字符转换,转换前后的字符长度必须相同
p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用
=:打印行号
l(小写L):打印数据流中的文本和不可以打印的ASCII字符(比如结束符$、制表符\t)

示例:

[root@localhost ~]# sed -e 'p' test       'p'打印 并且输出   一共两遍
1
1
2
2
3
3
4
4
[root@localhost ~]# sed -n -e  'p' test    -n禁止输出,-p只打印,就一遍
1
2
3
4
[root@localhost ~]# sed -n '=' test     打印行号,共四行
1
2
3
4
[root@localhost ~]# sed -n 'l' test    打印特殊ASCII,$符号
1$
2$
3$
4$
[root@localhost ~]# sed -n -e '='  -e  'p' test    -n禁止输出,=,行号,p,打印
#sed -n '=;p' test  等价于上面,因为一条命令,可以取消-e
-------------------------
1
1
2
2
3
3
4
4
[root@localhost ~]# sed -n '   换行实现 
> =
> p
> ' test
1
1
2
2
3
3
4
4

3.4、sed对指定行操作

3.4.1、查p

3.4.1.1、以数字形式表示行区间

[root@localhost ~]# sed -n '1p' test   打印第一行
1
[root@localhost ~]# sed -n '$p' test   打印最后一行
4
[root@localhost ~]# sed -n '1,3p' test  打印一到三行
1
2
3
[root@localhost ~]# sed -n '3,$p' test  打印第三行到最后一行
3
4
[root@localhost ~]# sed -n '1,+3p' test  打印1,再加3行,即1-4行
1
2
3
4
---------------------------------------------
[root@localhost ~]# sed -e '5q' test    -e,输出5行,q并退出
1
2
3
4
[root@localhost ~]# sed -n 'p;n' test  ‘p;n’打印,移动到下一行,所以打印1,移动到2,打印3,移动到4
1
3
[root@localhost ~]# sed -n 'n;p' test  ‘n;p’先移动到下行,再打印,移动1,打印2,移动3打印4
2
4
[root@localhost ~]# sed -n '2,${n;p}' test  打印除第一行后的奇数行
3
[root@localhost ~]# 

3.4.1.2、字符串过滤空行

[root@localhost ~]# sed -n '/root/p' /etc/passwd   打印出包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# sed -n '/^root/p' /etc/passwd  打印出以root为开头的行
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# sed -n '/bash$/p' /etc/passwd  打印出以bash为结尾的行
root:x:0:0:root:/root:/bin/bash
kervin24:x:1000:1000:kervin24:/home/kervin24:/bin/bash  
--------------------------------------------------------------
[root@localhost ~]# sed -n '/bash\|root/p' /etc/passwd  打印出包含bash或root的行
################## sed -n -r '/bash|root/p' /etc/passwd 打印出包含bash或root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
kervin24:x:1000:1000:kervin24:/home/kervin24:/bin/bash
--------------------------------------------------------------
[root@localhost ~]# sed -n '2,/root/p' /etc/passwd  打印第二行开始,到查找到root的行
bin:x:1:1:bin:/bin:/sbin/nologin          这是第二行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin     找到root
[root@localhost ~]# sed -n '/ro\{2,\}t/p' /etc/passwd   至少2个o组成的root,打印出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# 

3.4.2、删除d

因为是删除,所以无需禁止输出,所以不需要-n

[root@localhost ~]# sed '3d' test   删除第三行
1
2
4
[root@localhost ~]# sed '2,5d' test  删除2-5行
1
[root@localhost ~]# sed '$d' test   删除最后一行
1
2
3
------------------------------------------------
########删除空行
[root@localhost ~]# cat test 
1
2

3
4



[root@localhost ~]# grep -v "^$"  test      方法一  -v取反
1
2
3
4

[root@localhost ~]# cat test | tr -s "\n"   方法二  压缩
1
2
3
4
[root@localhost ~]# sed '/^$/d' test       方法三
1
2
3
4
[root@localhost ~]# sed '/nologin$/!d' /etc/passwd    !d取反删除
[root@localhost ~]# sed '/2/,/3/d' /etc/passwd     第一个包含2字符串的行删到第一个包含字符串3的行
###/n/,/m/    遇到n打开删除功能,直到遇见m,关闭删除功能

3.4.3、替换s(字符串替换)

行 范围 s/旧字符/新字符/替换标记
 c(整行替换)  y(对应字符进行替换,效果类似tr)

4种替换标记

  • 数字:表明新字符串将替换第几处匹配的地方

  • g:表明新字符将会替换所有匹配的地方

  • p:打印与替换命令匹配的行,与-n一起使用

  • w文件:将替换的结果写到文件中

替换第几个
---------------------------------------------------------
[root@localhost ~]# sed -n 's/root/admin/p' /etc/passwd
admin:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost ~]# sed -n 's/root/admin/2p' /etc/passwd
root:x:0:0:admin:/root:/bin/bash
[root@localhost ~]# sed -n 's/root/admin/3p' /etc/passwd
root:x:0:0:root:/admin:/bin/bash
[root@localhost ~]# 
---------------------------------------------------------
####gp  全部替换
[root@localhost ~]# sed -n 's/root/admin/gp' /etc/passwd
admin:x:0:0:admin:/admin:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
---------------------------------------------------------
#####1--10行前面添加’#‘
[root@localhost ~]# sed -n '1,10 s/^/#/p'  /etc/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
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
----------------------------------------------------------
[root@localhost ~]# sed -n '/^root/ s/^/#/p' /etc/passwd  以root为开头的行,前面添加’#‘
#root:x:0:0:root:/root:/bin/bash
-----------------------------------------------------------
###*.swap.*   含有swap   #&中   #表示注释符号  &表示通过正则表达式匹配到的行内容
[root@localhost ~]# sed -n 's/.*swap.*/#&/p'  /etc/fstab 
#/dev/mapper/centos-swap swap                    swap    defaults        0 0
------------------------------------------------------------
[root@localhost ~]# sed '1,10 s/^/#/w test01.txt'  /etc/passwd    保存在文件test01.txt
------------------------------------------------------------
###把/sbin/bash替换成/sbin/nologin   分隔符可以是别的任意
[root@localhost ~]# sed 's/\/sbin\/bash/\/sbin\/nologin/g' /etc/passwd
[root@localhost ~]# sed  's#/sbin/bash#/sbin/nologin#g' /etc/passwd
-------------------------------------------------------------
sed -f 文件    可以在文件里定义多条操作规则

3.4.5、增

[root@localhost ~]# sed '$a ABC'  test01.txt   最后一行添加ABC
[root@localhost ~]# sed '$i ABC'  test01.txt   最后一行前添加ABC
[root@localhost ~]# sed '6r file' test01.txt   在6行后添加文件内容file

3.4.6、复制粘贴

[root@localhost ~]# cat test02 
3457834
343444
333333
666666
99999
6666
6666
4444
2222
34322
4444
33
55845
[root@localhost ~]# sed '1,3 {H;d};$G' test02     1-3行剪切到最后一行,H复制,d删除,G粘贴
666666
99999
6666
6666
4444
2222
34322
4444
33
55845

3457834
343444
333333
---------------------------------------------
[root@localhost ~]# sed '1,3H;$G' test02        复制粘贴
3457834
343444
333333
666666
99999
6666
6666
4444
2222
34322
4444
33
55845

3457834
343444
333333

3.4.7、转换位置

[root@localhost ~]# echo 111222333 | sed 's/(111)(222)/\2\1/' -r
222111333
[root@localhost ~]# echo 111222333 | sed -r 's/^(.)(.*)(.)$/\3\2\1/'   交互头尾
311222331
[root@localhost ~]# 

4、awk编辑器

4.1、工作原理

  • 逐行读取文本,默认以空格或tab键为分隔符,将分割所得的各个字符保存到内建变量中,并按模式或条件执行编辑命令

  • sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个“字段”然后再进行处理。

  • awk信息的读入也是逐行读取的,执行结果可以通过print功能将字段数据打印显示。

  • 在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”,“||”表示“或”、“!”表示“非”;

  • 还可以进行简单的数学运算,如+、-、*、/、%、^、分别表示加、减、乘、除、取余和乘方

4.2、命令格式

awk 选项 ‘模式或条件{操作}’  文件1  文件2.....
awk -f 脚本文件  文件1 文件2

awk常见的内建变量(可直接用)如下所示:

FS:列分隔符。指定每行文本的字符分隔符,默认为空格或制表符。与“-F”作用相同

NF:当前处理的行的字符个数

NR:当前处理的行的行号(序数)

$0:当前处理的行的整行内容

$n:当前处理行的第n个字段(第n列)

FILENAME:被处理的文件名

RS:行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条的记录。而awk一次仅读入一条记录,以进行处理。预设值是‘\n’

4.3、一般用法

[root@localhost ~]# awk '{print $0}'  test01   打印文本内容
a
b
c
d
e
[root@localhost ~]# awk '{print}'  test01   打印文本内容
a
b
c
d
e
------------------------------------------------------------
[root@localhost ~]# awk 'NR==1,NR==3{print $0}'  test01      打印1-3行
a
b
c
[root@localhost ~]# awk '(NR>=1)&&(NR<=3){print} ' test01    打印1-3行
a
b
c
[root@localhost ~]# awk '(NR>=1)||(NR<=3){print} ' test01    满足一个条件,所以全部打印
a
b
c
d
e
[root@localhost ~]# awk '(NR==1)||(NR==3){print} ' test01   打印1或3行
a
c
------------------------------------------------------------
[root@localhost ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.96.105  netmask 255.255.255.0  broadcast 192.168.96.255
        inet6 fe80::880:99c7:2c24:11f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:c8:d2:cc  txqueuelen 1000  (Ethernet)
        RX packets 16604  bytes 1218845 (1.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3892  bytes 451161 (440.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ifconfig ens33 |awk 'NR==2{print $0 }'   打印第二行
        inet 192.168.96.105  netmask 255.255.255.0  broadcast 192.168.96.255
--------------------------------------------------------------
[root@localhost ~]# awk '(NR%2)==1{print }' test01      奇数行
a
c
e
[root@localhost ~]# awk '(NR%2)==0{print }' test01      偶数行
b
d
-------------------------------------------------------------
[root@localhost ~]# awk '/root/{print}'  /etc/passwd  输出包含root的行内容
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk '/^root/{print}'  /etc/passwd   输出root开头的行内容
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk '/bash$/{print}'  /etc/passwd   输出root结尾的行内容
root:x:0:0:root:/root:/bin/bash
kervin24:x:1000:1000:kervin24:/home/kervin24:/bin/bash
--------------------------------------------------------------
#######x=0,统计当bash$结尾时,x++,输出x个数
[root@localhost ~]# awk 'BEGIN{x=0};/bash$/{x++};END{print x}' /etc/passwd
2
以字段输出文本

[root@localhost ~]# awk 'BEGIN{FS=":"};{print $1,$3}' /etc/passwd   打印1,3列
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
---------------------------------------------------------------------
[root@localhost ~]# awk -F: '$3>500 {print $1,$3}' /etc/passwd     打印UDI>500的
polkitd 999
libstoragemgmt 998
colord 997
saslauth 996
setroubleshoot 995
chrony 994
geoclue 993
sssd 992
nfsnobody 65534
gnome-initial-setup 991
kervin24 1000
-------------------------------------------------------------------
[root@localhost ~]# awk -F: '{if($3>=1000){print}}' /etc/passwd      如果UID>=1000,则打印
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
kervin24:x:1000:1000:kervin24:/home/kervin24:/bin/bash
------------------------------------------------------------------
#######三元运算符  如果$3>$4,则取$3,否则$4
[root@localhost ~]# awk -F: '{max=($3>=$4)?$3:$4;{print max,$1}}' /etc/passwd
0 root
1 bin
2 daemon
4 adm
7 lp
5 sync
.......
------------------------------------------------------------------
[root@localhost ~]# awk  '{print NR,$0}' test01        打印行号和内容
1 a
2 b
3 c
4 d
5 e
-------------------------------------------------------------------
[root@localhost ~]# awk -F: '$7~"no" {print $1,$NF}' /etc/passwd    ~:某个字短包含某个字符
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nolo

4.4、高级用法

[root@localhost ~]# echo $PATH | awk 'BEGIN{RS=":"};{print NR,$0}'   每个字段按照行输出
1 /usr/local/sbin
2 /usr/local/bin
3 /usr/sbin
4 /usr/bin
5 /root/bin

[root@localhost ~]# echo $PATH | awk 'BEGIN{RS=":"};{print NR,$0};END{print NR}'最后NR为5  
1 /usr/local/sbin
2 /usr/local/bin
3 /usr/sbin
4 /usr/bin
5 /root/bin

5
-----------------------------------------------------------------------------
[root@localhost ~]# awk -F: '/bash$/{print | "wc -l"}' /etc/passwd  统计bash结尾并且交给wc
2
[root@kervin25 ~]# free            
              total        used        free      shared  buff/cache   available
Mem:        1867048      335756     1107480        9348      423812     1307656
Swap:       4194300           0     4194300
[root@kervin25 ~]# free | awk '/Mem:/ {print int($3/$2*100)"%"}'   统计cpu使用率
17%
-----------------------------------------------------------------------------
###date用法
[root@kervin25 ~]# date +"%Y%m%d"   获得这个月的年月日
20220501
[root@kervin25 ~]# date +"%Y%m01"   获得这个月的第一天
20220501
[root@kervin25 ~]# date -d $(date -d "1 month" +"%Y%m01") +"%Y%m%d"   获得下个月时间
20220601
[root@kervin25 ~]# date -d "2 day ago" +"%Y%m%d"    取得两天前的时间
20220429
[root@kervin25 ~]# cat /proc/uptim         #1、系统启动到现在的时间(秒) 2、系统空闲时间
8327.15 33131.73
[root@kervin25 ~]# date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%Y%m%d %H:%M:%S" 
20220501 09:36:36        ####得出系统上一次启动时间
-------------------------------------------------------------------------------
[root@kervin25 ~]# echo "A B C D" | tr " " "|"
A|B|C|D
[root@kervin25 ~]# echo "A B C D" | awk 'BEGIN{OFS="|"}; {$1=$1;print $0}  '
A|B|C|D
#####0FS输出分隔符,$1=$1,使得内建变量重新赋值,使得重新计算$0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值