shell脚本——sed详细介绍(包含应用案例)
Posted 0611#
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本——sed详细介绍(包含应用案例)相关的知识,希望对你有一定的参考价值。
Sed概述
- Sed是文本处理工具,依赖于正则表达式,可以读取文本内容,根据指定条件对数据进行添加、删除、替换等操作,被广泛应用于shell脚本,以完成自动化处理任务。
- Sed在处理数据时默认不直接修改源文件,而是把当前处理的行存储在临时缓存区中,所有指令都在缓冲区中操作,处理完成后,把缓冲区内容默认输出到屏幕,接着处理下一行内容,这样不断重复,直到文件末尾,文件本身内容没有改变。
- Sed是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。
- 接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作。
Sed处理模式
Sed 对输入的一行数据进行处理的模式,对整个文件进行重复执行此模式处理,在此说明对输入的一行数据处理的内在机制如下图所示:
- 首先读入文件流的一行到模式空间;
- 在模式空间内,对内容进行模式匹配处理;
- 输出处理后的数据内容;
- 清空当前模式空间;
- 读取第二行输入流到模式空间;
- 又开始对模式空间内的下一行输入数据进行处理。
Sed基本用法
命令语法: sed -e '编辑命令' 文件1 文件2...
sed -n -e '编辑命令' 文件1 文件2...
sed -i -e '编辑指令' 文件1 文件2...
常用选项:-e:指定要执行的命令,只有一个编辑命令时可省略
-n:只输出处理后的行,读入时不显示
-i:直接编辑文件,而不输出结果
编辑指令格式:[地址1] [地址2] 操作 [参数]
- 与grep一样,sed在文件查找时也可以使用正则表达式和各种元字符。
- 这里的“地址”就可以是正则表达式,也可以是数字、$,如果没有地址就代表是所有的行。
- 常用的“操作”及作用如下。“参数”一般用g代表只要符合条件,全部都进行处理。
指令 | 作用 |
---|---|
p | 输出指定的行 |
d | 删除指定的行 |
s | 字串替换,格式:“行范围 s/旧字符串/新字符串/g” |
r | 读取指定文件 |
w | 保存为文件 |
i | 插入,在当前行前面插入一行或多行 |
Sed返回值
- sed的返回值都是0
- 只有当命令存在语法错误的时候,sed的退出状态才是非0
Sed和正则表达式
与grep一样,sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符。正则表达式是括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符。
- 使用基本元字符:^、$、.、[]、 [ ^ ]、\\ <\\ >、\\ { \\ }
- 使用扩展元字符:?、+、|、()
使用扩展元字符的方式
- + :转义
- sed -r :sed使用正则表达式必须+r
汇总示例
常用参数 -r 、-i详解
- -r :sed的动作支持的是延伸型正则表示法的语法(默认的基础正则表示法语法)
- -i :直接修改读取的文件内容,而不是输出到终端
举例说明
示例文件准备:为了使操作结果看起来简单易懂在每一行最后添加了数字
[root@pakho ~]# head /etc/passwd >passwd #使用了账户文件中的前10行并输出到相对路径下的passwd文件
[root@pakho ~]# cat passwd
root:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
一、删除命令d
参数
操作成功但是文件不会发生修改!
[root@pakho ~]# sed -r '/root/d' passwd # d 参数要求必须加在匹配的字符串后面
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
如果说需要进行修改加上 -i 参数
[root@pakho ~]# sed -ri '/root/d' passwd
操作完成后重新还原文件passwd.txt 因为后续还要做实验就不再添加参数-i
d
参数同样可以使用行号修改文件
[root@pakho ~]# sed -r '3d' passwd
root:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
[root@pakho ~]# sed -r '3{d}' passwd #归于上述操作的另一种写法
root:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
[root@pakho ~]# sed -r '1,3d' passwd #将1-3行进行删除
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
二、★ 替换命令 s
参数
[root@pakho ~]# sed -r 's/原来/现在' passwd
[root@pakho ~]# sed -r 's/root/pakho/' passwd
pakho:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/pakho:/sbin/nologin10
[root@pakho ~]# sed -r 's/root/pakho/g' passwd #加g参数全局替换
[root@pakho ~]# sed -r 's/^root/pakho/' passwd #使用^行首定位符只会替换第一行的root
[root@pakho ~]# sed -r 's/[0-9][0-9]$/&5/' passwd #&调用前方匹配字符
root:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin105
vi编辑器也有类似的功能
在末行模式下输入
:% s/.*/#&/g #每一行前方添加注释
[root@pakho ~]# sed -r 's/(mail)/E\\1/g' passwd #将mail改成Email
...
Email:x:8:12:Email:/var/spool/Email:/sbin/nologin9
...
[root@pakho ~]# sed -r 's#(mail)#E\\1#g' passwd #将分隔符换成#号与上同
...
Email:x:8:12:Email:/var/spool/Email:/sbin/nologin9
...
三、读取文件 r
参数
参数 r 案例操作前分析逐行处理的概念: sed工作模式逐行处理
- 例:准备一个文件 使用 r 参数
[root@pakho ~]# cat 1.txt
/abc/123
[root@pakho ~]# sed -r 'r 1.txt' passwd #使用参数r 效果展示
root:x:0:0:root:/root:/bin/bash1
/abc/123
bin:x:1:1:bin:/bin:/sbin/nologin2
/abc/123
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
/abc/123
adm:x:3:4:adm:/var/adm:/sbin/nologin4
/abc/123
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
/abc/123
sync:x:5:0:sync:/sbin:/bin/sync6
/abc/123
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
/abc/123
halt:x:7:0:halt:/sbin:/sbin/halt8
/abc/123
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
/abc/123
operator:x:11:0:operator:/root:/sbin/nologin10
/abc/123
[root@pakho ~]# sed -r '$r 1.txt' passwd #$为最后一行表示为最后一行添加其他文件的内容
root:x:0:0:root:/root:/bin/bash1
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
/abc/123
[root@pakho ~]# sed -r '/root/r 1.txt' passwd #在root后面读取1.txt
root:x:0:0:root:/root:/bin/bash1
/abc/123
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
/abc/123
vi编辑器中的类似命令
:$ r 2.txt #在当前文件中,读取其他文件的内容
四、写文件命令 w
参数(另存为)
五、追加命令 a
参数 (之后)
[root@pakho ~]# sed -r 'a123' passwd #a在前 sed逐行处理
root:x:0:0:root:/root:/bin/bash1
123
bin:x:1:1:bin:/bin:/sbin/nologin2
123
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
123
adm:x:3:4:adm:/var/adm:/sbin/nologin4
123
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
123
sync:x:5:0:sync:/sbin:/bin/sync6
123
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
123
halt:x:7:0:halt:/sbin:/sbin/halt8
123
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
123
operator:x:11:0:operator:/root:/sbin/nologin10
123
[root@pakho ~]# sed -r '2a1111\\
> 2222\\
> 3333' passwd
六、插入命令 i
参数(之前)
七、★ 替换整行命令 c
参数
[root@pakho ~]# sed -r '1c11111111' passwd #第一行root被替换成了111
11111111
bin:x:1:1:bin:/bin:/sbin/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
实用案例:使用 sed + c 参数关闭selinux
[root@pakho ~]# sed -ri '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
八、获取下一行命令 n
参数
[root@pakho ~]# sed -r '/root/{n;d}' passwd #使用n参数将root下一行删除
root:x:0:0:root:/root:/bin/bash1
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
[root@pakho ~]# sed -r '/root/{n;s/bin/ding/g}' passwd #将root下一行的bin全局替换ding
root:x:0:0:root:/root:/bin/bash1
ding:x:1:1:ding:/ding:/sding/nologin2
daemon:x:2:2:daemon:/sbin:/sbin/nologin3
adm:x:3:4:adm:/var/adm:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
九、反向选择 !
参数
十、多重编辑 e
参数
[root@pakho ~]# sed -r -e '1,3d' -e '4s/adm/administra/g' passwd #删除1至3行并且同时将adm换成administra使用全局
administra:x:3:4:administra:/var/administra:/sbin/nologin4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin5
sync:x:5:0:sync:/sbin:/bin/sync6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown7
halt:x:7:0:halt:/sbin:/sbin/halt8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin9
operator:x:11:0:operator:/root:/sbin/nologin10
[root@pakho ~]# sed -r '1,3d;4s/adm/administra/g' passwd #上述案例的另外一种写法使用;隔开
实战案例
一、删除配置文件中的#号注释行
[root@pakho ~]# sed -r '/^#/d' /etc/vsftpd/vsftpd.conf #删除ftp服务器配置文件的注释行
- 效果展示
二、修改文件
[root@pakho ~]# sed -ri '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
修改selinux文件 很简单就不演示了
三、给多行文件添加注释
[root@pakho ~]# sed -ri '2,6s/^/#/' passwd #给文件passwd2至6行添加注释
- 效果展示
[root@pakho ~]# sed -ri '2,6s/(.*)/#\\1/'passwd
[root@pakho ~]# sed -ri '2,6s/.*/#&/' passwd #道理一样扩展多种方法
四、sed中使用外部变量
#准备工作
[root@pakho ~]# name=zhangsan #创建一个变量name
[root@pakho ~]# echo $name
zhangsan
#追加变量
[root@pakho ~]# sed -ri "1a$name" passwd #注意这里使用若引用 “” 强引‘’会导致$无法调用变量
- 效果展示
- 注意
[root@pakho ~]# sed -ri "$a$name" passwd #本来想在最后一行添加变量反而报错了
sed: -e expression #1, char 2: extra characters after command
# $是最后一行 a是追加 被误认为是变量$a
#正确写法
[root@pakho ~]# sed -ri "\\$a$name" passwd #添加转意符
- 效果展示
以上是关于shell脚本——sed详细介绍(包含应用案例)的主要内容,如果未能解决你的问题,请参考以下文章
自动化运维必须要学的Shell文本处理三剑客之——sed用法(超多案例详细介绍)