一、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]'