第八章 shell编程之sed

本文详细介绍了sed命令的概念、工作原理、基本语法,包括模式空间、保留空间的使用,以及如何进行文本替换、删除、插入等操作。提供了丰富的实例和练习题,帮助读者掌握sed在文本处理中的应用。
摘要由CSDN通过智能技术生成

目录

1.1. 概念

1.1.1. 工作原理:

1.2. 基本语法

1.2.1. 格式

1.2.2. 参数

1.2.3. 定址符

1.2.4. 操作

1.3. 输出文本

1.3.1. 范例文件:

1.3.2. 示例

1.4. 文本替换

1.4.1. 范例文件

1.4.2. 格式:

1.4.3. 示例

1.5. 删除文本

1.5.1. 注意

1.5.2. 示例

1.6. 插入文本

1.6.1. 注意

1.6.2. 格式

1.6.3. 示例1

1.6.4. 注意

1.7. 练习


1.1. 概念

sed命令是一个非交互式的文本编辑器,是将一系列的编辑命令应用于一批文本的理想工具,可以对来自文本文件以及标准输入的文本进行编辑。其中,标准输入可以是来自键盘、文件重定向、字符串、变量或者是管道的文本

sed命令拥有非交互式和高效的特点,可以为用户节约大量的时间

Vim 采用的是交互式文本编辑模式,可以用键盘命令来交互性地插入、删除或替换数据中的文本。但 sed命令不同,它采用的是流编辑模式,最明显的特点是,在 sed 处理数据之前,需要预先提供一组规则,sed 会按照此规则来编辑数据

1.1.1. 工作原理:

模式空间pattern space:sed在内存里开辟模式空间,处理文件的每个输入行,最多8192字节

保留空间holding space:sed在内存里开辟保留空间,保存已经处理过的输入行,最多8192字节

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

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

(2)执行:默认情况下,所有的sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed 命令 将会在所有的行上依次执行。

(3)显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空

(4)重复上述过程,直到将文件中所有数据处理完毕

图:

注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出

1.2. 基本语法

1.2.1. 格式

sed -参数 '[定址符]' '操作' 文件名

1.2.2. 参数

-n,--quiet,--silent:安静模式,不输出模式空间中的内容,在一般sed的用法中,所有来自STDIN的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来

-i:直接编辑原文件,而不是由屏幕输出,默认不对原文件进行操作

-e:直接在命令行模式上进行sed的动作编辑,多个子命令之间也可以用分号隔开,如:sed -e 'command1;command2... filename 或者 sed -e 'command1' -e command2' ……filename

-r:使用扩展正则表达式

-f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作

--help:显示帮助

--version:显示版本

-{} :可组合多个命令,以分号隔开

1.2.3. 定址符

用于使用数字指定处理的行区间,或者使用正则进行过滤

表示方法

1.2.4. 操作

s:替换,替换指定字符,一般搭配正则表达式
d:删除,删除选定的行。
p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以
ASCII 码输出。其通常与“-n”选项一起使用。
=:打印行号。
a:增加,a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
i:插入,i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
c:行替换,指定行中的所有内容,替换成该选项后面的字符串。
y:字符转换,转换前后的字符长度必须相同。
l(小写):打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t)
! :对指定行以外的所有行应用命令
& :代表匹配到的内容

1.3. 输出文本

1.3.1. 范例文件:

[root@server ~]# vim sed1.txt
one
two
three
four
five
six
seven
eight
nine
ten

1.3.2. 示例

[root@server ~]# sed -n 'p' sed1.txt # 全文打印

[root@server ~]# sed -n '=;p' sed1.txt # 同时打印行号

[root@server ~]# sed -n -e '=' -e 'p' sed1.txt # 同上

[root@server ~]# sed -n 'l' sed1.txt # 同时输出内容及控制字符
[root@server ~]# sed -n ' # 交互模式
> =
> p
> ' sed1.txt

[root@server ~]# sed -n '1p' sed1.txt # 打印第一行

[root@server ~]# sed -n '4,6p' sed1.txt # 打印4-6行

[root@server ~]# sed -n '3,9p' sed1.txt # 打印中3到9行内容

[root@server ~]# sed -n '7,$p' sed1.txt # 第7行到最后一行

[root@server ~]# sed -n '$p' sed1.txt # 打印最后一行

[root@server ~]# sed -n '2~2p' sed1.txt # 打印偶数行

[root@server ~]# sed -n '1~2p' sed1.txt # 打印奇数行

[root@server ~]# sed -n '4p;6p;8p' sed1.txt # 打印第4、6、8行

[root@server ~]# sed -n '1,+5p' sed1.txt # 打印第一行及其下5行

[root@server ~]# sed -n '1!p' sed1.txt # 打印除了第一行的剩余行

[root@server ~]# sed -n '/^f/p' sed1.txt # 正则检索以f开头

[root@server ~]# sed -n '/t/p' sed1.txt # 正则检索包含t的行

[root@server ~]# sed -n '/^t/p;/^f/p' sed1.txt # 正则检索以t开头或者f开头的行

[root@server ~]# sed -n '2,/five/p' sed1.txt # 检索第2行到five所在行的内容

[root@server ~]# sed -n '/n$/p' sed1.txt # 正则检索以n结尾的行

[root@server ~]# sed -n 'n;p' sed1.txt # 检索偶数行

[root@server ~]# sed -n 'p;n' sed1.txt # 检索奇数行

[root@server ~]# sed -n '$=' sed1.txt # 打印文本行数

1.4. 文本替换

1.4.1. 范例文件

[root@server ~]# cp /etc/passwd ~/ps
[root@server ~]# cat ps
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
……
……

1.4.2. 格式:

sed -参数 '行范围s/旧字符串/新字符串/替换标记' 文件名

行范围:使用数字表示,即对第几行到第几行进行替换处理,若省略则表示进行全文处理

s: 替换动作

/// :表示替换格式

替换标记

(1)数字:使用1-512之间的数字,表示指定需要替换的字符串出现第几次才进行替换

(2)g:对数据中所有匹配到的内容进行替换,若省略g则只会对第一次匹配的内容进行替换

(3)p:替换成功立刻打印,一般与-n一起使用

(4)w 文件名 : 将缓冲区的内容写入到指定文件中

(5)& : 使用正则表达式匹配的内容进行替换

(6)\ :转义符,若有特殊符号或路径则需要转义

1.4.3. 示例

[root@server ~]# sed 's/root/boot/g' ps # 替换root为boot

[root@server ~]# sed -n 's/root/admin/p' ps # 将每一行的第一个root替换为admin

[root@server ~]# sed -n 's/root/admin/2p' ps # 将本行第2次出现的root进行替换

[root@server ~]# sed -n 's/root/admin/gp' ps # 将文本中所有root全部替换

[root@server ~]# sed -n '4s/adm/root/gp' ps # 将第4行内容替换

# 将ps文件第4行的/sbin/nologin替换为/bin/bash,注意:路径的/必须要转义
[root@server ~]# sed -n '5s/\/sbin\/nologin/\/bin\/bash/p' ps

[root@server ~]# sed 's#/sbin/nologin#/bin/bash#g' ps # 同上,/可写为#

[root@server ~]# sed 's#root#boot#g' ps # 同上,但内容为#不能更改

[root@server ~]# sed -n '$s/:/@/gp' ps # 最后一行冒号替换为@

# 全文注释:即行首添加# ,#&表示在定位位置的左侧添加#
[root@server ~]# sed 's/^/#&/' ps

[root@server ~]# sed 's/^/#/' ps 可省略&

# 检索SSH行,在其单词左侧添加#,不能省略&,否则为替换
[root@server ~]# sed 's/SSH/#&/' ps

[root@server ~]# sed 's/SSH/&#/' ps # 检索SSH行,&#表示在其单词右侧添加#

[root@server ~]# sed 's/^/@&/g;s/$/&@/g' ps # 所有行首及行尾添加@,可省略&

[root@server ~]# sed '1s/^/\n/' ps # 第一行之前插入空白行

[root@server ~]# sed '$s/$/\n/' ps # 最后一行之后插入空白行

# 所有小写改大写,\u表示大写,&启用正则匹配
[root@server ~]# sed 's/[a-z]/\u&/g' ps

# 所有大写改小写,\l(注意是小写的L)表示小写,&启用正则匹配
[root@server ~]# sed 's/[A-Z]/\l&/g' ps

# 单词第一个字母大写,\b表示匹配词首边界
[root@server ~]# sed 's/\b[a-z]/\u&/g' ps
# 开启selinux
[root@server ~]# sed -i '7s/disabled/enforcing/' /etc/selinux/config
# 将22行的disabled替换为enforcing
# 使用sed更换httpd的网页默认目录
[root@server ~]# yum install nginx -y
[root@server ~]# sed -i '42s/\/usr\/share\/nginx\/html/\/www\/zy/' /etc/nginx/nginx.conf
# 使用替换实现删除

[root@server ~]# sed -n 's/root//gp' ps # 将全文中root替换为空,即删除

[root@server ~]# sed -n 's/^.//p' ps # 删除每行第一个字符,^.表示行首任意一个字符

[root@server ~]# sed -n 's/^#//p' /root/anaconda-ks.cfg # 将注释符#删除

[root@server ~]# sed -n 's/.$//p' ps # 删除每行最后一个字符

[root@server ~]# sed '5,10s/[0-9]//g' ps # 删除5-10行的所有数字

# 删除所有的特殊字符(除了数字及大小写字母),将结果写入到t1.txt文件中
[root@server ~]# sed 's/[^(a-z)(A-Z)(0-9)]//gw t1.txt' ps

1.5. 删除文本

1.5.1. 注意

d操作用于删除文本的特定行,会删除指定的所有内容,则使用该命令必须特别小心,若忘记指定处理行的话会删除所有内容,也不会有任何输出

[root@server ~]# sed -i 'd' ps # 全部清空
[root@server ~]# cat ps

1.5.2. 示例

[root@server ~]# cp /root/anaconda-ks.cfg / # 示例文件准备
[root@server ~]# sed '1d' /anaconda-ks.cfg # 删除第1行

[root@server ~]# sed '2,5d' /anaconda-ks.cfg # 删除2、5行

[root@server ~]# sed '8,$d' /anaconda-ks.cfg # 删除第8到结尾所有行

[root@server ~]# sed '$d' /anaconda-ks.cfg # 删除最后一行

[root@server ~]# line_number=1
[root@server ~]# sed "${line_number}d" /anaconda-ks.cfg # 删除某行,使用变量作为行号

[root@server ~]# sed '/^$/d' /anaconda-ks.cfg # 删除空白行

[root@server ~]# sed '/System/d' /anaconda-ks.cfg # 将包含Options的整行删除

[root@server ~]# sed -e '/System/d' -e '/Root/d' /anaconda-ks.cfg # 多个关键字

[root@server ~]# sed '/System/d' sos.conf | sed '/Root/d' /anaconda-ks.cfg # 同上

[root@server ~]# sed '/3/,/5/d' /anaconda-ks.cfg # 删除3所在行到5所在行之间的内容(包含)

[root@server ~]# sed '/^#/d' /anaconda-ks.cfg
# 注意:默认情况下,删除的内容只是在输出的结果中消失了,没有增减-i参数时源文件不变

1.6. 插入文本

1.6.1. 注意

使用a(append)动作在指定行的下一行追加一行,使用i(insert)动作在指定行前插入一行,两者格式相同

1.6.2. 格式

sed '行范围a(或i)\新文本' 文件名

1.6.3. 示例1

[root@server ~]# cat /etc/hosts
[root@server ~]# cp /etc/hosts ~/

# 尾部添加一行
[root@server ~]# sed -i '$a\192.168.48.132 www.openlab.com' ~/hosts

# 某行之前添加
[root@server ~]# sed -i '3i\192.168.48.131 www.openlab.com' ~/hosts

# 文本匹配后插入
[root@server ~]# sed -i '/131/i\192.168.48.130 www.openlab.com' ~/hosts

1.6.4. 注意

sed基于数据流处理的命令,若无内容则无法处理,所以空文件不能插入

[root@server ~]# touch t2.txt
[root@server ~]# cat t2.txt
[root@server ~]# sed -i '$a\xiao ming,18,98.5' t2.txt
[root@server ~]# cat t2.txt

1.7. 练习

习题1

示例:把/etc/passwd 复制到/root/test.txt,用sed打印所有行;
1、打印test.txt的3到10行;
2、打印test.txt 中包含’root’的行;
3、删除test.txt 的15行以及以后所有行;
4、删除test.txt中包含’bash’的行;
5、替换test.txt 中’root’为’toor’;
6、替换test.txt中’/sbin/nologin’为’/bin/login’
7、删除test.txt中5到10行中所有的数字;
8、删除test.txt 中所有特殊字符(除了数字以及大小写字母);
9、在test.txt 20行到末行最前面加’aaa:’
10、在test.txt所有行首增加#注释

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

习题2

# 打印4-8行
# 打印第3行及其下2行
# 打印中包含null的行
# 打印第5行到sshd所在行的内容
# 将全文的替换adm替换为admin
# 将全文的/bin/bash替换为/usr/bin/sh
# 将1-5行的单词第一个字母大写
# 在第5行之前插入一个空白行
# 安装bind,将/etc/named.conf的2项参数替换为any
# 删除所有的冒号
# 在最后一行之后添加一个空白行
# 删除root所在行
# 在第一行之前插入一条信息记录,内容自定

1.打印4-8行

2.打印第3行及其下2行

3.打印中包含null的行

4.打印第5行到sshd所在行的内容

5.将全文的替换adm替换为admin

6.将全文的/bin/bash替换为/usr/bin/sh

7.将1-5行的单词第一个字母大写

8.在第5行之前插入一个空白行

9.安装bind,将/etc/named.conf的2项参数替换为any

10.删除所有的冒号

11.在最后一行之后添加一个空白行

12.删除root所在行

13.在第一行之前插入一条信息记录,内容自定

习题3:

[root@server ~]# vim nowcoder.txt
zhangsan 30 18567198188
wangwu 20 13390789090
lisi 26 15129883716

[root@server ~]# cat nowcoder.txt
zhangsan 30 18567198188
wangwu 20 13390789090
lisi 26 15129883716

[root@server ~]# sed -r 's/([1-9]{3})([0-9]{4})([0-9]{4})$/\1-\2-\3/g' nowcoder.txt

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值