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脚本——正则表达式(包含grep详细介绍及应用)

自动化运维必须要学的Shell文本处理三剑客之——sed用法(超多案例详细介绍)

shell脚本——sed详细用法

shell脚本编程之正则表达式(扩展正则表达式sed)

shell脚本应用正则表达式grep,sed,awk,的应用

shell脚本应用正则表达式grep,sed,awk,的应用