RHCE的学习(26)

第九章 shell编程之sed

概念

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

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

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

工作原理:

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

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

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

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

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

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

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

  • 图:

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

基本语法

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

参数

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

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

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

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

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

  • --help:显示帮助

  • --version:显示版本

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

定址符

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

  • 表示方法

地址定界作用
1,5对文件的1-5行内容进行处理
2,$对文件的2到最后一行内容进行处理
1,+3对文件第1行以及以后的3行内容进行处理
1~2对文件的1,3,5,7,……的行内容进行处理
/正则表达式/对任何能够被正则表达式匹配到的行进行处理

操作

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

输出文本

范例文件:
[root@server ~]# vim  sed1.txt
one
two
three
four
five
six
seven
eight
nine
ten
示例
[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   # 打印文本行数

文本替换

范例文件
[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
……
……
格式:
sed  '行范围s/旧字符串/新字符串/替换标记'  文件名
  • 行范围:使用数字表示,即对第几行到第几行进行替换处理,若省略则表示进行全文处理

  • s: 替换动作

  • /// :表示替换格式

  • 替换标记

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

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

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

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

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

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

示例
[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 
# 将7行的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 

删除文本

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

[root@server ~]# sed  -i  'd'  ps  # 全部清空
[root@server ~]# cat  ps
示例
[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参数时源文件不变

插入文本

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

格式
sed  '行范围a(或i)\新文本'   文件名
示例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 
注意
  • 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

示例:把/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所有行首增加#注释 
  • 习题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:

[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 
  • 面试题2:

# 文件内容如下:
    123abc456
	456def123
	567abc789
	789def567

#	要求输出:
	456ABC123
	123DEF456
	789ABC567
	567DEF789

[root@server ~]# sed -r 's/([0-9]{3})(.*)([0-9]{3})/\3\2\1/' b.txt | tr -s '[a-z]' '[A-Z]'
456ABC123
123DEF456
789ABC567
567DEF789

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值