一、sed简介
sed是一种流编辑器,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变。
二、sed的语法
1.基本语法
cpp
sed OPTIONS... [SCRIPT] [INPUTFILE...]
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动作。
三.模式空间中的编辑操作
1.地址的定界
|----------------------------|------------------|----------------------------------------|
| 地址定界 | 示例 | 说明 |
| 不写地址定界 | | 表示对文件所有行进行处理 |
| num1,num2 | 1,3或者1,$ | 对文件的1-3行内容进行处理;如果是$表示文件 的最后一行 |
| num1,+N | 1,+3 | 对文件的num1行以及以后的N行内容进行处理 |
| first~step | 1~2 | 对文件的1,3,5,7,......的行内容进行处理 |
| /pattern/ | /^root/,/r/I | 对任何能够被正则表达式匹配到的行进行处理 |
| \%pattern% | \%/r% | 可以使用其他的边界符号(例如#),对任何能 够被正则表达式匹配到的行进行处理 |
| /pattern1/,/pattern2/ | /^root/,/^adm/ | 表示正则表达式1和正则表达式2匹配到的行和两 个正则表达式之间的所有行 |
| 0,/pattern1/或者1,/pattern1/ | 0,/^adm/ | 从第一行开始到能够被正则表达式匹配到的行之 间的所有内容 |
示例:
生成测试文件
cpp
[root@sen shell]# head -n 5 /etc/passwd > testfile
a.替换文件中所有:为@@@
cpp
[root@sen shell]# sed 's/:/@@@/g' testfile
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
b.替换1-3行的:
cpp
[root@sen shell]# sed '1,3s/:/@@@/g' testfile
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
c.替换1行和3行的:
cpp
[root@sen shell]# sed -e '1s/:/@@@/g' -e '3s/:/@/g' testfile
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
d.替换2行及其后2行:
cpp
[root@sen shell]# sed -e '2,+2s/:/@@@/g' -e '3s/:/@/g' testfile
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
e.每隔1行替换:
cpp
[root@sen shell]# sed -e '2~2s/:/@@@/g' testfile
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
f.带sbin字符忽略大小写的行替换:
cpp
[root@sen shell]# sed -e '/SBIN/Is/:/@@@/g' testfile
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
g.daemon和lp字符之间的行替换:
cpp
[root@sen shell]# sed -e '/daemon/,/lp/s/:/@@@/g' testfile
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
h.第1行到adm之间的
cpp
[root@sen shell]# sed -e '1,/adm/s/:/@@@/g' testfile
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
i.adm到最后一行的
cpp
[root@sen shell]# sed -e '/adm/,$s/:/@@@/g' testfile
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
j.其他sed分隔符的指定
cpp
[root@sen shell]# sed -e '\%adm%,$s%:%@@@%g' testfile
[root@sen shell]# sed -e '\#adm#,$s#:#@@@#g' testfile
2.常用编辑命令
|----------------------------|----------------------------------------------------------------------------------------------------------------|
| 对文件行内容的编辑 | 说明 |
| d | 删除匹配到的行 |
| p | 打印匹配到的行 |
| a 文本内容 | 将文本内容添加到匹配到的行的下一行 |
| i 文本内容 | 将文本内容添加到匹配到的行上一行 |
| c 文本内容 | 用文本内容替换匹配到的所有行 |
| r | 读入文件内容追加到匹配行后面 |
| R | 读入文件一行内容追加到匹配行后面 |
| w /dir/filename | 将匹配到的内容另存到/dir/filename中 |
| s/pattern/replacement/flag | 根据正则表达式进行匹配,将匹配到的内容替换为replacement, flag可以指定g(表示全局替换,默认只替换每行第一个)num1(表 示对匹配到的第几个内容进行替换),i(不区分大小写),p(如 果成功替换则打印) |
示例:
生成测试文件
cpp
[root@sen shell]# sed -e '\#adm#,$s#:#@@@#g' testfile
a.删除行
cpp
[root@sen shell]# sed '1d' testfile
[root@sen shell]# sed '$d' testfile
[root@sen shell]# sed '/root/d' testfile
[root@sen shell]# sed '/root/!d' testfile
b.显示行
cpp
[root@sen shell]# sed -n '1p' testfile
[root@sen shell]# sed -n '$p' testfile
[root@sen shell]# sed -n '/root/p' testfile
[root@sen shell]# sed -n '/root/!p' testfile
c.添加行
cpp
[root@sen shell]# sed '1ahello world' testfile
[root@sen shell]# sed '$ahello world' testfile
[root@sen shell]# sed '/adm/ahello world' testfile
[root@sen shell]# sed '/adm/ahello world' testfile
[root@sen shell]# sed '/adm/!ahello\nworld' testfile
d.插入行
cpp
[root@sen shell]# sed '1ihello world' testfile
[root@sen shell]# sed '$ihello world' testfile
[root@sen shell]# sed '/adm/ihello world' testfile
[root@sen shell]# sed '/adm/ihello world' testfile
[root@sen shell]# sed '/adm/!ihello\nworld' testfile
e.替换行
cpp
[root@sen shell]# sed '1chello world' testfile
[root@sen shell]# sed '$chello world' testfile
[root@sen shell]# sed '/adm/chello world' testfile
[root@sen shell]# sed '/adm/chello world' testfile
[root@sen shell]# sed '/adm/!chello\nworld' testfile
f.整合文件
cpp
[root@sen shell]# vim numfile1
1
5
6
[root@sen shell]# vim numfile2
2
3
4
[root@sen shell]# sed '1rnumfile2' numfile1
[root@sen shell]# sed '1Rnumfile2' numfile1
g.保存处理结果
cpp
[root@sen shell]# sed '/root/w file' testfile
[root@sen shell]# cat file
root:x:0:0:root:/root:/bin/bash
h.字符替换
cpp
[root@sen shell]# sed 's/:/##/' testfile
[root@sen shell]# sed 's/:/##/2' testfile
[root@sen shell]# sed 's/:/##/g' testfile
[root@sen shell]# sed 's/^./##/g' testfile
[root@sen shell]# sed 's/^\<[a-Z]*[a-Z]\>//' testfile
元素向后引用
[root@sen shell]# sed 's/^\(...\)\(t\)/\2/g' testfile
t:x:0:0:root:/root:/bin/bash
3.特殊符号的使用
|------|------------------------------------|
| 特殊符号 | 说明 |
| ! | 对指定行以外的所有行应用命令 |
| = | 打印当前行行号 |
| ~ | "first~step"表示从first行开始,以步长step递增 |
| & | 代表匹配到的内容 |
| ; | 实现一行命令语句可以执行多条sed命令 |
| {} | 对单个地址或地址范围执行批量操作 |
| + | 地址范围中用到的符号,做加法运算 |
示例:
!示例
cpp
[root@sen shell]# sed -n '/root/!p' testfile
=示例
cpp
[root@sen shell]# sed '=' testfile
~示例
cpp
[root@sen shell]# sed '1~2s/:/##/g' testfile
&示例
cpp
[root@sen shell]# sed 's/:/^&^/g' testfile
; 示例
cpp
[root@sen shell]# sed -n '1p;3p' testfile
{}示例
cpp
[root@sen shell]# sed -n '1,3p;1,3=' testfile
[root@sen shell]# sed -n '1,3{p;=}' testfile
+示例
cpp
[root@sen shell]# sed -n '1,+1p' testfile
四、模拟面试训练
1.给定一个文件,要求在文件每一行前加入行号并用空格隔开内容
cpp
[root@sen shell]# sed '=' testfile | sed 'N;s/\n/ /g'
2.给定文件按要求完成文件内容
cpp
文件内容如下:
123abc456
456def123
567abc789
789def567
要求输出:
456ABC123
123DEF456
789ABC567
567DEF789
cpp
[root@sen shell]# sed -r 's/([0-9]{3})(.*)([0-9]{3})/\3\2\1/' b.txt | tr -s
'[a-z]' '[A-Z]'