正则表达式之sed

目录

一、sed简介

二、sed 流编辑器的工作过程

三、sed命令

3.1 基本格式

3.2 执行多条命令的格式

3.3 常用选项

3.4 常用操作符

3.5 sed命令打印功能

3.5.1 默认打印方式

3.5.2 sed命令的寻址打印

3.5.3 文本模式过滤行内容

3.5.4 sed的删除操作

3.5.6 sed命令替换

格式

替换标记

sed命令的替换符

3.5.7 sed命令的增加

3.5.7 sed命令中字符串和字符的位置交换

3.5.8 sed -f 指定命令来对第二个文件的行进行处理

扩展例题

总结


一、sed简介

sed 即 Stream EDitor,和 vim 不同,sed是行编辑器

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,

称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,

把缓冲区的内容送往屏幕。

接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

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

二、sed 流编辑器的工作过程

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

  • 读取: sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space )。
  • 执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
  • 显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

注意:默认情况下所有的sed命令都是在模式空间内执行的,

因此输入的文件并不会发生任何变化,除非使用"sed -i"修改源文件、或使用重定向输出到新的文件中。

三、sed命令

3.1 基本格式

sed -e '操作' 文件1 文件2

sed -e '操作' 文件1 文件2

sed -f 脚本文件 文件1 文件2

sed -i -e '操作' 文件1 文件2

3.2 执行多条命令的格式

方式一:

sed -e '操作1' -e '操作2' 文件

sed -n -e '/^r/p' -e '/^b/p' /etc/passwd

方式二:

sed -e '操作1;操作2' 文件

3.3 常用选项

选项说明
-e 或--expression=

表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用

-f 或--file=

表示用指定的脚本文件来处理输入的文本文件

-h 或--help

显示帮助

-i

直接修改目标文本文件 慎用

-n

仅显示script处理后的结果

3.4 常用操作符

操作符说明
s

替换,替换指定字符

d

删除,删除选定的行

a

增加,在当前行下面插入一行指定内容

i

插入,在选定行上面插入一行指定内容

c

替换,将选定行替换为指定内容

y

字符转换,转换前后的字符长度必须相同

p

打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。其通常与“-n”选项一起使用。

=

打印行号

l

打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t)

r

扩展正则表达式

sed最为核心的功能是增删改查

3.5 sed命令打印功能

[root@localhost ~]#sed '' /etc/fstab #查看文件内容

[root@localhost opt]# sed '' < /etc/fstab #可以支持重定向输入

[root@localhost opt]# cat /etc/passwd |sed '' #也可以支持管道符

[root@shell 98]# sed '' /etc/fstab    #查看文件内容

#
# /etc/fstab
# Created by anaconda on Mon Jul 29 18:29:03 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=9eefb0bb-b2b5-45a2-bf1f-031a954cae18 /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

3.5.1 默认打印方式

[root@www rh]# sed -e 'p' test1.txt  --sed有一个默认输出,加上P,会打印两行
123
123
345
345
789
789
000
000



[root@www rh]# sed -n 'p' test1.txt  ---n禁止了默认输出,就只有一行
123
345
789
000

仅打印第几行

[root@shell 98]# ifconfig ens33 | sed -n '2p'       #打印第二行
        inet 192.168.23.10  netmask 255.255.255.0  broadcast 192.168.23.255

打印时对行号的操作

[root@shell 98]# sed -n '=' 1.txt    #只显示行号
1
2
3
4
5
6
7
8
9
10
[root@shell 98]# cat 1.txt
123
123
435
234
54
574
54
54
54
[root@shell 98]# sed -n '=;p' 1.txt    ---显示行号和每行的内容
1
123
2
123
3
435
4
234
5
54
6
574
7
54
8
54
9
54
10

3.5.2 sed命令的寻址打印

方式一:按照行号寻求内容

[root@localhost sed]#sed -n '1p' test1.txt --打印第一行

[root@localhost sed]#sed -n '4p' test1.txt --打印第四行

[root@localhost sed]#sed -n '$p' test1.txt --打印最后一行

方式二:进行行号范围区间的打印

[root@localhost sed]#sed -n '1,3p' test1.txt --打印1-3行

[root@localhost sed]#sed -n '5,$p' test1.txt --打印第五行到最后一行

[root@localhost sed]#sed -n '2,+2p' test1.txt ---打印第二行+两行的内容,相当于2,4p

[root@localhost opt]#sed -n '3p;5p' test1.txt ---输出第三行和第五行

[root@shell 98]# sed -n '1,+3p' 1.txt    #打印第一行再加三行   相当于1,4
123
123
435
234

方式三:指定间隔打印

[root@localhost sed]#sed -n -e '2p' -e'$p' test1.txt ---打印第二行和最后一行

[root@localhost sed]#sed -n -e '2p' -e'3p' test1.txt ---打印第二行和第三行

方式四:对奇数行和偶数行的打印

[root@localhost sed]#sed -n 'n;p' test1.txt ---打印偶数的行

[root@localhost sed]#sed -n 'p;n' test1.txt ---打印奇数的行

n在p前面,跳过一行,打印下一行,就是偶数行;在后面,就是打印第一行,然后跳过一行,形成奇数行

3.5.3 文本模式过滤行内容

方式一:对包含的字符串进行过滤打印

[root@localhost sed]#sed -n '/o/p' test1.txt ---包含o的所有行

[root@localhost sed]#sed -n '/th/p' test1.txt ---包含th的所有行

方式二:应用基础正则表达式进行打印

[root@localhost sed]#sed -n '/^root/p' /etc/passwd --以root为开头的所有内容,全文本搜索

[root@localhost sed]#sed -n '/bash$/p' /etc/passwd --以bash结尾的所有内容,全文本搜索

[root@localhost sed]#sed -n '4,/bash$/p' /etc/passwd --从第四行开始,一直打印到第一个以bash为结尾的所在行

方式三:使用扩展正则表达式进行打印

注意:

sed -r 支持扩展正则表达式。同时在 使用{n}、{n,}、{n,m}时,括号{}前不需要加反斜杠\ 。

[root@localhost sed]# sed -r -n '/(99:){2,}/p' /etc/passwd ---包含有两个99:的内容所在行

[root@localhost sed]# sed -r -n '/^root|bash$/p' /etc/passwd ---包换以root开头,或者以bsah结尾的内容所在行

3.5.4 sed的删除操作

sed -i 时会对文本进行实际操作(建议对目标文件先进行备份,再进行操作)

通过行号进行删除

[root@localhost sed]#sed 'd' test1.txt ---删除所有,什么也不打印

[root@localhost sed]#sed -n '3d;p' test1.txt ---删除第三行,打印剩余的所有内容

[root@localhost sed]#sed -n '5,8d;p' test1.txt ---删除5到8行,打印剩余的所有内容

[root@localhost sed]#sed -n '5,$d;p' test1.txt ---删除5到最后一行行,打印剩余的所有内容

[root@localhost sed]#sed '4,6!d' test1.txt ---除了4-6行,其他的全部删除

如果要生效:sed -i -n

匹配字符串内容删除

[root@localhost sed]#sed '/one/d' test1.txt ---删除包含one的行

[root@localhost sed]#sed '/one/,/six/d' test1.txt ---删除one-six的行

[root@localhost sed]#sed '/one/,/six/!d' test1.txt ---除了one-six的行,其余的全部删除,反向删除

[root@localhost sed]#sed '/six/!d' test1.txt ---除了six的行,其余的全部删除,反向删除

字符串搭配正则进行删除:

[root@localhost sed]#sed '/^$/d' test1.txt ---通过^$,来删除空行;

删除空行的三种方法:

grep -v "^$" test1.txt ----过滤出非空行

cat test1.txt |tr -s "\n" ----压缩换行符

sed '/^$/d' test1.txt ----删除空行

3.5.6 sed命令替换

格式

行范围 s/旧字符串/新字符串/替换标记

替换标记

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

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

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

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

sed命令的替换符

s:替换字符串

c:整行替换

y:字符替换,替换前后的字符串长度必须相同

[root@localhost sed]#sed -n 's/root/test/2p' /etc/passwd --指定每一行的第二个root,替换为了test

[root@localhost sed]#sed -n 's/root/test/gp' /etc/passwd --所有的root都替换为test

[root@localhost sed]#sed -n '/^root/ s/^/#/p' /etc/passwd --以root开头开始处理,把开头为空的替换为#,注释掉

字母字符进行大小写的替换

[root@localhost sed]#sed 's/[A-Z]/\l&/g' test1.txt ---将大写全部转换为小写,

l&(小写字母)是转换小写的一种特殊的符号,前面要加转义符“\”

[root@localhost sed]#sed 's/[a-z]/\u&/' test1.txt ---把首字母替换成大写,

u&是转换首字母大写的一种特殊的符号,前面要加转义符“\”

整行替换

[root@localhost sed]# sed '/ONE/c 22' test1.txt        #包含ONE字符的所有行都替换为22

[root@localhost sed]# sed '/TWO/c TEST' test1.txt        #包含TWO字符的所有行都替换为TEST

单字符的替换

使用y,是对单个字符进行替换,每个字符需要一一对应,不是整体替换。前后字符串长度需要一致,不然会报错

只要有匹配的单字符会全部替换

[root@localhost sed]# sed 'y/TH/12/' test1.txt        #字符长度一样,12替换TH

3.5.7 sed命令的增加

a:在下一行添加内容

i:在上一行插入内容

r:在行后读入文件内容

[root@localhost sed]# sed '/three/a 123' test1.txt #行后

[root@localhost sed]# sed '/three/i 123' test1.txt #上一行

[root@test1 opt]# sed '/three/r test.sh' 123.txt #当前行的下一行

[root@shell 98]# sed '/root/a 123' passwd    #在root行下面添加123
root:x:0:0:root:/root:/bin/bash
123
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

[root@localhost sed]# sed '$r test2.txt' test1.txt ---先读取test1内容,然后在test1的末行插入test2的所有内容

[root@localhost opt]# sed '$a 123' 123.txt #在123.txt的文件最后一行插入123

[root@localhost opt]# sed '$i 123' 123.txt #在123.txt的文件最后后面的行中插入    倒数第二行

[root@shell 98]# sed '$r 3.txt' 1.txt
123
123
435
234
54
574
54
54
54

asf
Afsd

[root@shell 98]# cat 1.txt
123
123
435
234
54
574
54
54
54

[root@shell 98]# cat 3.txt
asf
Afsd

3.5.7 sed命令中字符串和字符的位置交换

[root@localhost opt]# echo ky29ztt | sed -r 's/(ky29)(ztt)/\2\1/'

yhtky27

[root@localhost opt]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\3\2\1/'

dxlyhtky27

[root@localhost opt]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\2\1/'

yhtky27

[root@localhost opt]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\3\1/'

dxlky27

[root@localhost opt]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\3\2/'

dxlyht

 [root@localhost sed]#echo 123abc|sed -r 's/(.)(.)(.)(.)(.)(.)/\6\5\4\3\2\1/' #前面的点表示字符位置,后面的数字表示对应的交换顺序

3.5.8 sed -f 指定命令来对第二个文件的行进行处理

[root@localhost opt]# cat 123.txt

/IPADDR=192.168.233.21/c IPADDR=10.10.10.10

[root@localhost opt]# cat 456.txt

IPADDR=192.168.233.21

[root@localhost opt]# sed -f 123.txt 456.txt

IPADDR=10.10.10.10

扩展例题

提取版本号

[root@localhost opt]# grep -E "[0-9]+." 1.txt
ant-1.9.7.jar
ant-launcher-1.9.7.jar
antlr-2.7.7.jar
antlr-runtime-3.4.jar
aopalliance-1.0.jar
archaius-core-0.7.6.jar
asm-5.0.4.jar
aspectjweaver-1.9.5.jar
bcpkix-jdk15on-1.64.jar
bcprov-jdk15-1.46.jar
bcprov-jdk15on-1.64.jar
checker-compat-qual-2.5.5.jar

[root@localhost opt]# cat 1.txt |sed -r 's/(.)-(.)(.jar)/\1\2\3/' #完整版
[root@localhost opt]# cat 1.txt |sed -r 's/.-(.)(.jar)/\1\2/'     #把-前面的取消了
[root@localhost opt]# cat 1.txt |sed -r 's/.-(.).jar/\1/'         #把.jar是不在引用,正确结果
#-r 表示引用扩展正则,(.)表式"-"前面的所有,"-",就是"-",第二个(.)表示"-"后面的内容到.jar,(.jar)的第三个部分
1.9.7
1.9.7
2.7.7
3.4
1.0
0.7.6
5.0.4
1.9.5
1.64
1.46
1.64
2.5.5

 查看指定时间内的日志

[root@localhost ~]#sed -n '/2023:08:09/,/2023:09:42:37/p' /var/log/messages #没有内容
[root@localhost network-scripts]# sed -n '/Mar 23 21:00:01/,/Mar 23 21:30:01/p' /var/log/messages #开头的格式要一致
Mar 23 21:00:01 localhost systemd: Started Session 70 of user root.

修改网卡的IP地址

[root@localhost network-scripts]# sed -i '/IPADDR=192.168.233.21/c IPADDR=10.10.10.10' ifcfg-ens33
[root@localhost network-scripts]# cat ifcfg-ens33
TYPE=Ethernet            
DEVICE=ens33            
ONBOOT=yes                
BOOTPROTO=static        
IPADDR=10.10.10.10
NETMASK=255.255.255.0    
GATEWAY=192.168.233.2    
DNS1=192.168.233.2
[root@localhost network-scripts]# sed -i 'y/10.10.10.10/192.168.233.21/' ifcfg-ens33  #用单个字符串替换会报错
sed:-e 表达式 #1,字符 29:“y”命令的字符串长度不同

总结

1.sed命令是一种流编辑器读取文件会进行逐行读取加上指令操作,所以过大的文件一定要拆分后再交给sed处理

2.sed -r 搭配扩展正则表达式使用,使用{n} {n,} {n,m} 不需要加“\”

3.用 -i 时一定要先备份(尤其对重要文件的操作),或者时先实验好确定无误时,再使用 -i

4.sed 命令 的重点在于增删改查四个功能,可以运用在脚本中对重要文件配置的修改,添加等作用尤其有效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值