shell法宝之sed,修改文件内容的好帮手

一、概述

  • sed是一种流编辑器,会在编辑数据之前基于预先提供的一组规则来编辑数据流
  • sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本中

1.1 工作流程

读取、执行、显示

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

默认情况下所有的命令都是在缓冲区完成,所有输入的文件本身不会发生变化,除非我们手动进行重定向存储

1.2 命令格式

  • 第一种
sed -e '操作' 文件1 文件2 ...
sed -n -e '操作' 文件1 文件2 ...
sed -f 脚本文件 文件1 文件2
sed -i -e '操作' 文件1 文件2 ...
  • 第二种
sed -e 'n{
操作1
操作2
...
}' 文件1 文件2 ...

二、常用选项

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

三、常用操作

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

四、命令代码的使用

4.1 打印内容

sed 'p' cc.sed		# 打印文件内容

在这里插入图片描述

sed -ne 'p' cc.sed			# 打印内容

在这里插入图片描述

sed -ne '=' cc.sed			# -n显示行号,不显示内容

在这里插入图片描述

sed -ne 'l' cc.sed				# 打印文本,包括不可打印的字符$

在这里插入图片描述

4.2 寻址方式

两种

  • 以数字形式来表示区间
  • 用文本模式来过滤出行

部分简易命令

以 “ cc.sed ” 文本为模板,按照以下命令完成需求

sed -n '1p' cc.sed 		# 打印第一行内容
1

sed -n '5p' cc.sed 		# 打印第五行内容
5

sed -n '$p' cc.sed 		# 打印最后一行,$代表最后
0

sed -n '2,5p' cc.sed 	# 打印2至5行的内容
2
3
4
5

sed -n '2,+5p' cc.sed 	# 打印第二行开始,往后数五行
2
3
4
5


sed -n '8,$p' cc.sed 	# 打印第八行到最后
6
7
8
9
0

sed -n 'p;n' cc.sed 	# 打印奇数行
1
3
5

7
9

sed -n 'n;p' cc.sed 	# 打印偶数行
2
4

6
8
0

sed -n '5,${n;p}' cc.sed 	# 从第五行开始,打印偶数行至最后

6
8
0

系统文件内过滤需求

  • 过滤passwd文件内有root信息的
sed -n '/root/p' /etc/passwd			# 搜索带有root信息
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
  • 过滤 “ a ” 开头的行
sed -n '/^a/p' /etc/passwd				# 以a开头的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

  • 过滤 “ nologin ” 结尾的行,$表示结尾
sed -n '/nologin$/p' /etc/passwd			# 过滤noligin结尾的行,内容较多,筛选部分
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
  • 查找 “ ftp ” 和 “ root ” 的相关行
第一种:
sed -n '/ftp\|root/p' /etc/passwd		# | 表示或,需要用反斜杠 \ 来注释,否则无法检索
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

第二种:
sed -nr '/ftp|root/p' /etc/passwd		# 使用-r命令可以不需要添加反斜杠
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

  • 从搜索固定行数至内容的命令
sed -n '2,/sync/{=;p}' /etc/passwd		# 从第二行打印到包含sync的则一行,配合-n可以看行号
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
sync:x:5:0:sync:/sbin:/bin/sync
  • 根据检索条件匹配出内容,-r表示支持扩展正则表达式
[root@ccc lianxi]# sed -nr '/ro{1,}t/p' /etc/passwd			# 匹配一位及以上o,得出结果rot和root都可以出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

4.3 删除方式

简单的几个命令

sed 'd' cc.sed 			# 删除所有内容

sed '5d' cc.sed 		# 删除第五行
1
2
3
4


6
7
8
9
0

sed '2,8d' cc.sed 		# 删除2到8行
1
7
8
9
0

sed '$d' cc.sed 		# 删除最后一行
1
2
3
4
5


6
7
8
9
[root@ccc lianxi]# 		# 删除空行
1
2
3
4
5
6
7
8
9
0

对系统文件做更改

  • 删除passwd文件内 nologin 结尾的行
sed '/nologin$/d' /etc/passwd		# nologin结尾,$代表结尾
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
dcc:x:1000:1000:dcc:/home/dcc:/bin/bash
  • 除了 nologin ,其他都删除
sed '/nologin$/!d' /etc/passwd			# 只留下结尾 nologin 的行
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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
  • 从1开始删除,一直删除到4结束,不区分字符数量
    模板
    在这里插入图片描述

  • sed ‘/1/,/4/d’ cc.sed

  • 删除从1开头的到4开头的行,和前面的删除1到4行有区别
    在这里插入图片描述

4.4 替换

格式

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

替换标记

  • 数字:表示新字符串将要替换到第几处所匹配的地方
  • g:表面新字符串将要替换所有匹配的地方
  • p:打印与替换命令相匹配的行,与 “ -n ” 共同使用
  • w 文件:将替换的结果写到指定的文件中

模板

  • 替换passwd文件内的 root 为 AAAAA
  • 不加数字默认只会替换匹配到的第一个内容
  • 按行匹配
sed -n 's/root/AAAAA/p' /etc/passwd			# 替换root为AAAAA
AAAAA:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/AAAAA:/sbin/nologin

sed -n 's/root/AAAAA/2p' /etc/passwd		# 加了数字2,只有一条符合条件(第二位root被替换)
root:x:0:0:AAAAA:/root:/bin/bash
  • 匹配到的 root 全都替换 AAAAA
sed -n 's/root/AAAAA/gp' /etc/passwd		# g代表全部替换
AAAAA:x:0:0:AAAAA:/AAAAA:/bin/bash
operator:x:11:0:operator:/AAAAA:/sbin/nologin
  • 给行的开头添加 “ # ”
sed '1,5 s/^/#/' cc.sed 		# ^代表行首,1,5表示选中第1至5行
#1
#2
#3
#4
#5


6
7
8
  • 给指定1开的行末尾加上 “ # ”
sed '/^1/ s/$/#/' cc.sed 		# ^代表开头,在匹配行的末尾加上#
1#
2
3
4
5


6
7
8
9
0
11#
22
  • 将passwd文件内的第1-15行写入到新的文件中,并在开头加上#
sed '1,15 s/^/#/w ceshi.txt' /etc/passwd
cat ceshi.txt 
#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
#games:x:12:100:games:/usr/games:/sbin/nologin
#ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
#nobody:x:99:99:Nobody:/:/sbin/nologin
#systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
#dbus:x:81:81:System message bus:/:/sbin/nologin
  • 替换passwd文件内 bin/bash 为 bin/csh
  • !号为字符串的分隔符
sed -n 's!/bin/bash!/bin/csh!p' /etc/passwd		# !/bin/bash!为原有字符 /bin/csh!为新字符,用!号分隔开
root:x:0:0:root:/root:/bin/csh
dcc:x:1000:1000:dcc:/home/dcc:/bin/csh
123456:x:1001:1001::/home/123456:/bin/csh
ccd:x:1002:1002::/home/ccd:/bin/csh
ddccdd:x:1003:1003::/home/ddccdd:/bin/csh
dccccccc:x:1004:1004::/home/dccccccc:/bin/csh
ccccc:x:1005:1005::/home/ccccc:/bin/csh
ccaa:x:1006:1006::/home/ccaa:/bin/csh
ccaacc:x:1007:1007::/home/ccaacc:/bin/csh
dcc666:x:1008:1008::/home/dcc666:/bin/csh
ccaz:x:1009:1009::/home/ccaz:/bin/csh
  • 将文本内74577更换为7676
sed -i 's7\745\7\77\76\767g' cc.sed		# s后面的7为分隔符,并不是我们认知的7,需要用\来转义,后面出现的7同样需要,否则会和替换符重叠
cat cc.sed 
1
2
3
5
2
6
7676

4.5 插入

  • 将文件内第三行内容替换为 ABC
sed '/3/c ABC' cc.sed 		# 3表示第三行, c为替换
1
2
ABC
5
2
6
7676
  • 替换文件内7676为ABCD
[root@ccc lianxi]# sed '/7676/ y/7676/ABCD/' cc.sed 		# 选定7676 替换,必须同样位数替换
1
2
3
5
2
6
ABAB
  • 在文件内1到3行的下方插入ABCD
sed '1,3a ABCD' cc.sed 		# a为文件下方增加一行内容,i为文件上方增加
1
ABCD
2
ABCD
3
ABCD
5
  • 将文件内第三行内容剪切到末尾
sed '/3/{H;d};$G' cc.sed		# H表示复制,G表示粘贴,因为需求是剪切,所以需要用 d 删除原有的内容
1
2
5
2
6
7676


3
  • 123ABC 对调为 CBA321
  • 方法比较古板
echo "123ABC" | sed -r 's/(1)(2)(3)(A)(B)(C)/\6\5\4\3\2\1/'
CBA321
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值