shell -sed工具使用

简介

  • sed工具式:
    - stream EDitor,流式编辑器
    - 非交互式,基于模式模式匹配过滤及修改文本
    - 逐行处理(特点),并将结果输出到屏幕中
    - 可以实现对文本的输出,删除,替换,复制,剪切,到处,等各种操作

  • 命令格式

    • 主要用法:
      • 格式1:前置命令 | sed [选项] ‘编辑指令’
      • 格式2:sed [ 选项 ] ‘编辑指令’ 文件……

编辑指令 —> [定址符号]处理动作
定址符 --> [地址1地址2]]

  • 格式解析

    • 常见命令选项
      - -n : 屏蔽默认输出(全部文本)
      - -i : 直接修改文本内容
      - -r : 启用扩展的正则表达式,若与其他选项一起使用,应作为首个选项
    • 条件,可以式行号或者/正则/
      - 行号可以使用当个数字表示单行
      - 或者3,5表示连续的多行
      - 省略条件,则默认逐行处理全部文本
      - 匹配正则时,需要使用 #
  • 基本的处理动作
    - 常用动作指令

操作符用途指示示例
p打印行2,4p 输出第2、3、5、4行
d删除行2p;4p 输出第2、4行
s字符串替换s/old/new/(将每一行的第一个old替换成new)、 s/old/new/3(将每一行的第三个old替换成new)、s/old/new/g(将每一行的所有old替换成new)
  • sed [选项] ‘条件指令’ 文件… …
  • 支持正则表达式:
[root@room13pc37 ~]#head -5 /etc/passwd > /root/1.txt 	#先准备一份练习文件
[root@room13pc37 ~]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
...#省略
#先直接使用动作指令
#用sed显示文本的内容:
[root@room13pc37 ~]# sed  'p' 1.txt 		#直接使用动作指令 “p”显示1.txt的文本内容
root:x:0:0:root:/root:/bin/bash
....#省略
--------------------------
#注意:我们会发现我们的1.txt文件只有5行内容,但是我们使用sed工具输出,它把文本内容输出两次。
#这是应为sed的特点是:逐行处理,显示到屏幕当中,所以在我们用“p”命令输出1.txt文本内容时间,默认还会显示多一次,对此我们可以使用-n来取消默认输出。
---------------------------
[root@room13pc37 ~]# sed -n  'p' 1.txt 		#取消默认输出
root:x:0:0:root:/root:/bin/bash
...#省略

[root@room13pc37 ~]# sed -n  '1,4p' 1.txt 		#输出1到4行的内容
root:x:0:0:root:/root:/bin/bash
...
[root@room13pc37 ~]# sed -n "1p;3p" 1.txt		#输出1、3行的内容
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@room13pc37 ~]# sed -n '2,+2p' 1.txt 		#大家需要注意,+2p是指前面输出行的后面2行的内容。需要注意前面输出的是第2行的内容,所以一共输出的是3行内容
bin:x:1:1:bin:/bin:/sbin/nologin				#第2行的内容
daemon:x:2:2:daemon:/sbin:/sbin/nologin			# 第2行后面的2行内容
adm:x:3:4:adm:/var/adm:/sbin/nologin

[root@room13pc37 ~]# sed -n "1~2p" 1.txt 		#输出1,3,5行的内容,1~2是表示:从第1行开始输出,间隔输出两行。同理 2~2p :输出2,4,6行的文本内容。
root:x:0:0:root:/root:/bin/bash					#第1行内容
daemon:x:2:2:daemon:/sbin:/sbin/nologin			#第3行内容
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin		#第5行内容

[root@room13pc37 ~]# head -5 /etc/passwd >  /root/3.txt | sed -n 'p' 3.txt  
root:x:0:0:root:/root:/bin/bash
...#省略
[root@room13pc37 ~]# 
  • 使用正则表达式做定址符
[root@room13pc37 ~]# sed -n '/root/p' /etc/passwd		#搜索包含root的行
[root@room13pc37 ~]# sed -n '/^root/p' /etc/passwd		#搜索以root开头的行
[root@room13pc37 ~]# sed -n '/bash$/p' /etc/passwd		#搜索以bash结尾的行
  • sed工具的p、d、s操作指令案例集合

    • sed工具的p指令案例集锦(自己提前生成一个test.txt文件)
    [root@room13pc37 shell_test]# sed  -n 'p' test.txt           #输出所有行,等同于cat test.txt
    [root@room13pc37 shell_test]# sed  -n '4p' test.txt          #输出第4行
    [root@room13pc37 shell_test]# sed  -n '4,7p' test.txt        #输出第4~7行
    [root@room13pc37 shell_test]# sed  -n '4,+10p' test.txt      #输出第4行及其后的10行内容
    [root@room13pc37 shell_test]# sed  -n '/^bin/p' test.txt     #输出以bin开头的行
    [root@room13pc37 shell_test]# sed  -n '=' test.txt          #输出文件的所有行号
    [root@room13pc37 shell_test]# sed  -n '$=' test.txt          #输出文件的最后一行的行号
    [root@room13pc37 shell_test]# sed  -n '/root/=' tset_sed.s.txt #说出文件包含root的行数
    
    
    • sed工具的d指令案例集锦(提前生成一个test.txt文件)
    [root@room13pc37 shell_test]# sed  '3,5d' test.txt             #删除第3~5行
    [root@room13pc37 shell_test]# sed  '/xml/d' test.txt            #删除所有包含xml的行
    [root@room13pc37 shell_test]# sed  '/xml/!d' test.txt         #删除不包含xml的行,!符号表示取反
    [root@room13pc37 shell_test]# sed  '/^install/d' test.txt    #删除以install开头的行
    [root@room13pc37 shell_test]# sed  '$d' test.txt                #删除文件的最后一行
    [root@room13pc37 shell_test]# sed  '/^$/d' test.txt             #删除所有空行
    
    • sed命令的s替换基本功能(s/旧内容/新内容/选项)
    [root@room13pc37 shell_test]#vim  test.txt               #新建素材文件
    2017 2011 2018
    2017 2017 2024
    2017 2017 2017	
    
    [root@room13pc37 shell_test]#sed 's/2017/xxxx/'           test.txt	#把当前所有行的第一个2017都替换
    [root@room13pc37 shell_test]#sed 's/2017/xxxx/g'          test.txt	#替换的是的当前行的所有
    [root@room13pc37 shell_test]#sed 's/2017/xxxx/2'          test.txt	#替换的是当前行的的第二个2017
    [root@room13pc37 shell_test]#sed 's/2017#2'              test.txt	#把所有行中的第二2017替换成 空,相当于删除。
    [root@room13pc37 shell_test]#sed -n 's/2017/xxxx/p'      test.txt	#把所有行的第一个2017都替换调,同时显示所替换的行结果。
    
    [root@room13pc37 shell_test]# head  /etc/passwd > tset_sed.s.txt	#素材文件
    [root@room13pc37 shell_test]# sed -n 's/^root/xxx/p' tset_sed.s.txt	#把root开头所在的行给替换
    xxx:x:0:0:root:/root:/bin/bash
    
    [root@room13pc37 shell_test]# sed -n 's//bin/bash//bin/sh/p' tset_sed.s.txt	#	/ 过多系统无法识别,无法认为 “ /bin/bsah ”是一个整体
    sed:-e 表达式 #1,字符 8:“s”的未知选项
    [root@room13pc37 shell_test]# sed -n 's/\/bin\/bash/\/bin\/sh\/p' tset_sed.s.txt		#可以通过反斜杆来 " /bin/bash  "的 / 转义
    
    #同时我们可以使用其他字符来代替  " s /// "的次操作符号。(数字键(0~9)上的符号都可以使用, 要求操作的符号一致即可)
    [root@room13pc37 shell_test]# sed -n 's$/bin/bash$/bin/sh$p' tset_sed.s.txt
    root:x:0:0:root:/root:/bin/sh
    
    #增加注释、取消注释
    [root@room13pc37 shell_test]#  sed '4,7s/^/#/'   test.txt         //将第4~7行注释掉(行首加#号)
    [root@room13pc37 shell_test]#  sed 's/^#an/an/'  test.txt         //解除以#an开头的行的注释(去除行首的#号)
    
  • 例子 替换文件的内容:

#首先创建一个素材文件
[root@room13pc37 shell_test]# cat nssw.txt
hello the world
ni hao ma beijing

#删除文件中每行的第二个、最后一个字符
#分两次替换操作,第一次替换掉第2个字符,第二次替换掉最后一个字符:
#方法1
[root@room13pc37 shell_test]# sed 's/.//2;s/.$//' nssw.txt		# 用 . 来匹配任意一个字符。实现删除	多个个动作指令用 ; 隔开
hllo the worl
n hao ma beijin
#方法2
[root@room13pc37 shell_test]# sed -r 's/^(.)(.)(.*)(.)$/\1\3\4/;s/(.*)(.)$/\1/' nssw.txt
hllo the worl
n hao ma beijin

#将文件中每行的第一个、倒数第1个字符互换
#每行文本拆分为“第1个字符”、“中间的所有字符”、“倒数第1个字符”三个部分,然后通过替换操作重排顺序为“3-2-1
[root@room13pc37 shell_test]# sed -r 's/^(.)(.*)(.)$/\3\2\1' nssw.txt	#互换位置	
dello the worlh
gi hao ma beijinn
[root@room13pc37 shell_test]# sed -r 's/^(.)(.*)(.)$/\3\1/' nssw.txt	#删除中间部分内容。
dh
gn

#1.使用拓展的正则,需要加 -r选项。	
#2.() 是保留的作用。 
#3.^(.)==保留第一行开头的字符;同理(.)$ ==保留最后一行的字符。		
#4.保留的字符可以使用	\1、\2、\3 分别来代替 前面的()的内容。可以通过重排实现字符之间位置互换,类是与粘贴、剪切。
#5.有多个()就表示有多少部分,对于多少个\num。 \num的数量不能大于()的部分
-----------------------------------------------------------------------------------
  • 例子把该文件的中的数字,行首的空格删除掉
[root@room13pc37 shell_test]# cat nssw.txt
Hello the wo8rod
    ni h4ao m6a beijing		#前面是有空格的
#方法1
[root@room13pc37 shell_test]# sed -r 's/[0-9]//g;s/^( *)(.*)/\2/' nssw.txt		#使用() 保留的方法,  注意:( *)括号里面有空格
Hello the worod
ni hao ma beijing
#方法2
[root@room13pc37 shell_test]# sed -r 's/^ +//;s/[0-9]//g' nssw.txt   # "^ +" 之间有一个空格
Hello the worod
ni hao ma beijing

#若要保存修改,可以加上 -i 选项
  • 例子找出该文件的中的大写字母,并且给大写字母加行括号
[root@room13pc37 shell_test]# cat nssw.txt
Hello The worod
ni hao ma Beijing

[root@room13pc37 shell_test]# sed -r 's/([A-Z])/(\1)/g' nssw.txt		#使用() 粘贴复制,给\1加上()
(H)ello (T)he worod
ni hao ma (B)eijing

#[A-Z] 在这里是每一个行逐个查找

  • 应用1编写anonftp.sh脚本,用来装配匿名FTP服务
#!/bin/bash
yum -y install vsftpd
cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.old		#把源有的文件做一个备份,
sed -i 's/^#anon_u/anon_u /' /etc/vsftpd/vsftpd.conf
chmod o+w /var/ftp/pub
systemctl restart vsftpd
systemctl enable vsftpd

sed 文本块处理

  • 文本块处理动作:
操作符用途指令集合
i行前插入文本2iYY (在第2行之前添加文本行“YY”), 4,7iYY (在第4-7 行的每一行前添加文本)
a行后插入文本2aYY (在第2行之后追加文本“YY”)、 /^XX/aYY (在以XX开头的行后添加文本 )
c替换当前行2cYY (将第2行的内容修改为 “YY” )
  • 应用
#单行文本处理
[root@server0 shell]# cat abc		#素材文件
#a
[root@server0 shell]# sed  'a 666' abc	#在文本行的每一行后面添加
[root@server0 shell]# sed '1a 666' abc	#在文本行的第一行后面添加
#c
[root@server0 shell]# sed '1c 666' abc	#在文本行的每一行替换
[root@server0 shell]# sed 'c 666' abc	#在文本行的第一行替换
#i
[root@server0 shell]# sed 'i 666' abc	#在文本行的每一行前面添加
[root@server0 shell]# sed '1i 666' abc	#在文本行的第一行前面添加

#多行文本处理


  • 导入到处操作
    • 基本动作
      • -r 动作结合 -i 选项才会存入,否则只是输出
      • -w 动作以覆盖的方式另存为新文件
操作符用途指令集合
r读取文件3rb.txt (在第3行下方插入文本b.txt)、4.7rb.txt(在第4到7行后插入文件b.txt)
w保存到文件3wc.txt (在第3行另存为文本c.txt)、4.7wc.txt(在第4到7行另存为文件c.txt)
[root@server0 shell]# sed 'r 123' abc
[root@server0 shell]# touch 123
[root@server0 shell]# sed 'w 123' abc
abcd
666
xyz
[root@server0 shell]# cat 123
abcd
666
xyz
[root@server0 shell]# sed 'w 1234' abc		#若写入覆盖的文件的文件不存在,则会自动创建该文件
abcd
666
xyz
[root@server0 shell]# ls
1234  abc  123

sed综合脚本应用

1. 本案例要求编写脚本getupwd.sh,实现以下需求:
	找到使用bash作登录Shell的本地用户
	列出这些用户的shadow密码记录
	按每行“用户名 --> 密码记录”保存到getupwd.log
[root@server0 shell]# cat getupwd.sh
#!/bin/bash
A=$(sed -n '/bash$/s/:.*//p' /etc/passwd)
for i in A
do
        pass1=$(grep $i /etc/shadow)
        pass2=${pass1#*:}
        pass3=${pass2%%:*}
        echo "$i ----> $pass3"
done
[root@server0 shell]# bash getupwd.sh
A ----> $6$UiGI4Tc2$htsXYn5cJnOqv3P1VLcUSgfjDu2pL5yiJBuua6foZAHdwqeuLHfYUfS/vBn27Wjvoel8EJgtdsMjyquqvKAmf1
  • 总结:
    总结知识点:

#sed [选项] ‘条件指令’ 文件

选项:

		-n 屏蔽默认输出
		-r 支持扩展正则
		-i 修改源文件

条件:

行号 4 4,5 4~2 4,+10

/正则/
指令:

p 打印

d 删除

s 替换s/旧/新/g

a 追加

i 插入

c 替换行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值