shell编程之sed编辑器

shell编程之sed编辑器

  • 一、sed简介
  • 二、sed的工作流程
  • 三、sed命令的常用选项
  • 四、sed命令的操作符
  • 五、sed命令的寻址打印
  • 六、文本模式过滤行内容
  • 七、sed的删除操作
  • 八、sed命令替换
  • 九、sed命令的增加
  • 十、分组
  • 十一、sed -f
  • 十二、面试题
    • 12.1 提取版本号
    • 12.2 查看指定时间内的日志
    • 12.3 修改网卡的IP地址

一、sed简介

sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。

sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。

sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

二、sed的工作流程

  • 读取: sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space )。
  • 执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
  • 显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行, 直至所有内容被处理完。

在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非使用"sed -i"修改源文件、或使用重定向输出到新的文件中。

三、sed命令的常用选项

选项 含义
-e 或–expression= 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用
-f 或–file= 表示用指定的脚本文件来处理输入的文本文件
-h 或–help 显示帮助
-i 直接修改目标文本文件**(慎用)**
-n 仅显示script处理后的结果,过滤sed的默认输出

四、sed命令的操作符

操作符 含义
s 替换,替换指定字符
d 删除,删除选定的行
a 增加,在当前行下面增加一行指定内容
i 增加,在当前行上面增加一行指定内容
c 替换,将选定行替换为指定内容
y 字符转换,转换前后的字符长度必须相同
p 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,
则以 ASCII 码输出。其通常与“-n”选项一起使用
= 打印行号
l(小写L) 打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t)
r 扩展正则表达式
  • sed最为核心的功能是增删改查
[root@localhost opt]# sed -e 'p' test1.txt  	---sed有一个默认输出,加上P,会打印两行
123
123
345
345
789
789
000
000
[root@localhost opt]# sed -n 'p' test1.txt  	---n禁止了默认输出,就只有一行
123
345
789
000
[root@localhost opt]# ifconfig ens33 | sed -n 2p  #打印第二行
        inet 192.168.147.100  netmask 255.255.255.0  broadcast 192.168.147.255

#打印时对行号的操作 
[root@localhost opt]# sed -n '=' test1.txt  ---只显示行号
[root@localhost opt]# sed -n '=;p' test1.txt ---显示行号和每行的内容

五、sed命令的寻址打印

方式一:按照行号寻求内容

[root@localhost opt]# sed -n '1p' test1.txt --打印第一行
[root@localhost opt]# sed -n '4p' test1.txt --打印第四行
[root@localhost opt]# sed -n '$p' test1.txt --打印最后一行

方式二:进行行号范围区间的打印

[root@localhost opt]# sed -n '1,3p' test1.txt   --打印1-3行
[root@localhost opt]# sed -n '5,$p' test1.txt   --打印第五行到最后一行
[root@localhost opt]# sed -n '2,+2p' test1.txt  ---打印第二行+两行的内容,相当于2,4p
[root@localhost opt]# sed -n '3p;5p' test1.txt  ---输出第三行和第五行

方式三:指定间隔打印

[root@localhost opt]# sed -n -e '2p' -e'$p' test1.txt  ---打印第二行和最后一行
[root@localhost opt]# sed -n -e '2p' -e'3p' test1.txt  ---打印第二行和第三行 

方式四:对奇数行和偶数行的打印

[root@localhost opt]# sed -n 'n;p' test1.txt ---打印偶数的行
[root@localhost opt]# sed -n 'p;n' test1.txt ---打印奇数的行
n在p前面,跳过一行,打印下一行,就是偶数行;在后面,就是打印第一行,然后跳过一行,形成奇数行

六、文本模式过滤行内容

方式一:对包含的字符串进行过滤打印

[root@localhost opt]# sed -n '/o/p' test1.txt  ---包含o的所有行
[root@localhost opt]# sed -n '/th/p' test1.txt  ---包含th的所有行

方式二:应用基础正则表达式进行打印

[root@localhost opt]# sed -n  '/^root/p' /etc/passwd  --以root为开头的所有内容,全文本搜索
[root@localhost opt]# sed -n  '/bash$/p' /etc/passwd  --以bash结尾的所有内容,全文本搜索
[root@localhost opt]# sed -n  '4,/bash$/p' /etc/passwd  --从第四行开始,一直打印到第一个以bash为结尾的所在行

方式三:使用扩展正则表达式进行打印
注意:

sed -r 支持扩展正则表达式。同时在 使用{n}{n,}{n,m}时,括号{}前不需要加反斜杠\[root@localhost opt]# sed -r -n  '/(99:){2,}/p' /etc/passwd  ---包含有两个99:的内容所在行
[root@localhost opt]# sed -r -n  '/^root|bash$/p' /etc/passwd ---包换以root开头,或者以bsah结尾的内容所在行

七、sed的删除操作

注意:sed -i 时会对文本进行实际操作(建议对目标文件先进行备份,再进行操作)

通过行号进行删除

[root@localhost opt]# sed 'd' test1.txt          ---删除所有,什么也不打印
[root@localhost opt]# sed -n '3d;p' test1.txt    ---删除第三行,打印剩余的所有内容 
[root@localhost opt]# sed -n '5,8d;p' test1.txt  ---删除5到8行,打印剩余的所有内容 
[root@localhost opt]# sed -n '5,$d;p' test1.txt  ---删除5到最后一行行,打印剩余的所有内容 
[root@localhost opt]# sed '4,6!d' test1.txt      ---除了4-6行,其他的全部删除
如果要立即生效:sed -i -n 

匹配字符串内容删除

[root@localhost opt]# sed '/one/d' test1.txt          ---删除包含one的行
[root@localhost opt]# sed '/one/,/six/d' test1.txt    ---删除one-six的行
[root@localhost opt]# sed '/one/,/six/!d' test1.txt   ---除了one-six的行,其余的全部删除,反向删除
[root@localhost opt]# sed '/six/!d' test1.txt         ---除了six的行,其余的全部删除,反向删除

字符串搭配正则进行删除:

[root@localhost opt]# sed '/^$/d' test1.txt   ---通过^$,来删除空行;

删除空行的三种方法:

grep -v "^$" test1.txt     ----过滤出非空行
cat test1.txt |tr -s "\n"  ----压缩换行符
sed '/^$/d' test1.txt      ----删除空行

八、sed命令替换

格式:
行范围 s/旧字符串/新字符串/替换标记  
选项 含义
s 替换字符串
c 整行替换
y 字符替换,替换前后的字符串长度必须相同
[root@localhost opt]# sed -n 's/root/test/2p' /etc/passwd  --指定第二个root,替换为了test
[root@localhost opt]# sed -n 's/root/test/gp' /etc/passwd  --所有的root都替换为test
[root@localhost opt]# sed -n '/^root/ s/^/#/p' /etc/passwd  --以root开头开始处理,把开头为空的替换为#,注释掉

字母字符进行大小写的替换:

[root@localhost opt]# sed 's/[A-Z]/\l&/g' test1.txt  ---将大写全部转换为小写,l&是转换小写的一种特殊的符号,前面要加转义符“\”

[root@localhost opt]# sed 's/[a-z]/\u&/' test1.txt   ---把首字母替换成大写,
u&是转换首字母大写的一种特殊的符号,前面要加转义符“\[root@localhost opt]# sed 's/[a-z]/\U&/g' test1.txt  ---末尾加上了一个g,全部转换成大写

整行替换:

[root@localhost opt]# sed '/ONE/c 22' test1.txt  		---ONE为被替换的内容,22为替换后的内容
[root@localhost opt]# sed '/TWO/c TEST' test1.txt
  • 面试题:将ifcfg-ens33中的IP地址改为 10.10.10.10
cat /etc/sysconfig/network-script/ifcfg-ens33 | sed '/^IPADDR=192.168.147.100/c IPADDR=10.10.10.10'

单字符的替换

使用y,是对单个字符进行替换,每个字符需要一一对应,不是整体替换。前后字符串长度需要一致,不然会报错只要有匹配的单字符会全部替换

[root@localhost opt]# sed 'y/TH/12/' test1.txt 

九、sed命令的增加

a:在下一行添加内容

i:在上一行插入内容

r:在行后读入文件内容

[root@localhost opt]# sed '/three/a 123' test1.txt 			#行后
[root@localhost opt]# sed '/three/i 123' test1.txt  		#上一行
[root@localhost opt]# '/three/r test.sh' 123.txt 			#当前行的下一行
[root@localhost opt]# sed '$r test2.txt' test1.txt  	---先读取test1内容,然后再test2的末行插入test2的所有内容
[root@localhost opt]# sed '$a 123' 123.txt 					#在123.txt的文件最后一行插入123
oneoneone

oneoneone
twotwotwo

oneoneone
twotwotwo

oneoneone
twotwotwo
123
[root@localhost opt]# sed '$i 123' 123.txt 					#在123.txt的文件最后后面的行中插入123
oneoneone

oneoneone
twotwotwo

oneoneone
twotwotwo

oneoneone
123
twotwotwo

十、分组

()表示分组

[root@localhost opt]# echo abc123 | sed -r 's/(abc)(123)/\2\1/'
123abc
[root@localhost opt]# echo qweasdzxc | sed -r 's/(qwe)(asd)(zxc)/\3\2\1/'
zxcasdqwe
[root@localhost opt]# echo qweasdzxc | sed -r 's/(qwe)(asd)(zxc)/\2\1/'
asdqwe
[root@localhost opt]# echo qweasdzxc | sed -r 's/(qwe)(asd)(zxc)/\3\1/'
zxcqwe
[root@localhost opt]# echo qweasdzxc | sed -r 's/(qwe)(asd)(zxc)/\3\2/'
zxcasd


[root@localhost sed]#echo 123abc|sed -r 's/(.)(.)(.)(.)(.)(.)/\6\5\4\3\2\1/'  #前面的点表示字符位置,后面的数字表示对应的交换顺序
cba321
[root@localhost opt]# echo 北京欢迎你 |sed -r 's/(.)(.)(.)(.)(.)/\5\4\3\2\1/'
你迎欢京北

十一、sed -f

sed -f 用第一个文件的内容对第二个文件进行处理。

[root@localhost opt]# cat 123.txt
/IPADDR=192.168.147.100/c IPADDR=10.10.10.10
[root@localhost opt]# cat 456.txt 
IPADDR=192.168.147.100
[root@localhost opt]# sed -f 123.txt 456.txt 
IPADDR=10.10.10.10

[root@localhost opt]# cat abc.txt 
s/ /_/g									#将" "替换成"_"
[root@localhost opt]# cat abc2.txt 
hello world
abc def
[root@localhost opt]# sed -f abc.txt abc2.txt
hello_world
abc_def

十二、面试题

12.1 提取版本号

文件内容:

ant-1.9.7.jar
ant-launcher-1.9.7.jar
antlr-2.7.7.jar
antlr-runtime-3.4.jar
aopalliance-1.0.jar
archaius-core-0.7.6.jar
asm-5.0.4.jar
aspectjweaver-1.9.5.jar
bcpkix-jdk15on-1.64.jar
bcprov-jdk15-1.46.jar
bcprov-jdk15on-1.64.jar
checker-compat-qual-2.5.5.jar

[root@localhost opt]# cat 1.txt |sed -r 's/(.*)-(.*)(\.jar)/\2/'    
#-r 表示引用扩展正则,(.*)表式"-"前面的所有,"-",就是"-",第二个(.*)表示"-"后面的内容到.jar,(\.jar)的第三个部分
1.9.7
1.9.7
2.7.7
3.4
1.0
0.7.6
5.0.4
1.9.5
1.64
1.46
1.64
2.5.5

12.2 查看指定时间内的日志

[root@localhost opt]# sed -n '/Jun 8 21:00:01/,/Jun 8 21:30:0/p' /var/log/messages
  • 注意:时间的格式要和日志文件中的时间格式相同

12.3 修改网卡的IP地址

[root@localhost network-scripts]# sed -i '/IPADDR=192.168.147.100/c IPADDR=10.10.10.10' ifcfg-ens33 
[root@localhost network-scripts]# cat ifcfg-ens33 
TYPE=Ethernet			
DEVICE=ens33			
ONBOOT=yes				
BOOTPROTO=static		
IPADDR=10.10.10.10
NETMASK=255.255.255.0	
GATEWAY=192.168.147.2	
DNS1=8.8.8.8

你可能感兴趣的:(linux,运维,bash)