sed 流(行)编辑器

著有文本处理三剑客之称:grep , sed , awk

sed作为其中之一对于文本处理可谓是异常强大,能够大批量处理文本复杂繁琐的修改,添加,删除等操作,并能够完美的与正则表达式相结合使用.
处理文本时按数据流进行处理,每次读取文本的一行,将其放入缓冲区中称之为模式空间(pattern space),也可类比理解为工作台,然后根据地址定界或是正则表达式进行匹配,如果被匹配则执行其后的命令作出相应处理动作,而后读取下一行处理,不断重复.
值得注意的是sed默认会将读取到模式空间中的行输出到标准输出(一般是屏幕),并将处理完成后的行输出至标准输出.默认对文件本身不处理,仅处理模式空间中被模式匹配的行.

sed 命令使用格式:

sed [option] 'AddressCommand' input-file...
sed  可选项   '地址定界命令'  处理文本(可以是多个文件的列表处理)

option选项:
-n:只显示符合条件的行,静默模式关闭上面提到的默认打印模式空间至标准输出
-i:直接修改源文件(做任何修改操作之前先备份.bak)
-f:从文件读取编辑脚本(符合sed语法的脚本并非bash脚本)
-e:指定多个sed语法脚本,类似grep -e用法多点处理
-r:支持扩展的正则表达式
Address地址定界:

1. startline,endline  从第几行到几行

sed -n '1,100p' /var/log/yum.log /var/log/messages
   $:最后一行
     sed -n '$p' /var/log/yum.log
 $-1:最后第二2行
 1,+2d:删除第一行和紧跟其后的后两行(注意删除操作不加-n才可看到效果)
     sed '1,+2d' /etc/fstab
 ~:步进
     1~2p 从第一行开始,每次跳两行,也即奇数行
     1~2p 偶数行

2. /regexp/ 正则表达式匹配

/^root/

3./patternl/,/pattern2/ 第一次匹配到pattern1的行开始到第一次被pattern2匹配的行为止(注意并不是仅匹配一次,如果处理的文本中存在多个符合条件的组合将处理每个分组)
Command命令(触发动作):

  d:删除匹配的行,没被匹配的反而显示  
  p:显示匹配的行  
  a \string:在匹配到行后面追加显示stringa  
      \n 换行  
  i \string:在匹配到行前面追加显示string  
  c \string :替换,将string覆盖匹配的行  
  r file:将指定文件添加到匹配的行处  
  w file:将匹配到的内容另存至文件中  
  = 匹配的行加行号  
  ! 取反,没有被匹配的行做处理动作
替换和查找:

s/pattern/string/:  将pattern中匹配的字符串替换成string字符串,默认只处理模式空间中第一次被模式匹配的块,可通过其后的修饰符进行调整作用范围

   sed 's/fstab/testFSTAB/p' /etc/fstab    #将fstab替换为testFSTAB

标记符:

   g:全局          
   i:忽略大小写

s/ / /的形式也可是s@ @ @s# # # 甚至一些其他的字符作为分界,可自行测试
 匹配表达式和要替换的字符串之间可支持后向引用
   s/()/\1/:将第一个匹配的模式括号的内容引用到后面的\1处替换字符串
   &:对string字段引用,pattern中匹配的整个字符串

sed实例演示:

1.地址定界

显示/etc/fstab的9-12行

[root ~]# sed -n '9,12p' /etc/fstab
/dev/mapper/vg_root-lv_root /                       ext4    defaults        1 1
/dev/mapper/vg_root-lv_app /app                    ext4    defaults        1 2
UUID=9a92c305-beee-467f-9fe4-fd90b2e49743 /boot                   ext4    defaults        1 2
/dev/mapper/vg_root-lv_home /home                   ext4    defaults        1 2

2.步进及删除

查找/etc/fstab中除前7行后的奇数行(多种不同形式达到相同效果)

[root ~]# cat -n  /etc/fstab|sed  -n -e '1,7d' -e '1~2p'(注两个-e的内容不可反写)
 9  /dev/mapper/vg_root-lv_root /                       ext4    defaults        1 1
11  UUID=9a92c305-beee-467f-9fe4-fd90b2e49743 /boot                   ext4    defaults        1 2
13  tmpfs                   /dev/shm                tmpfs   defaults        0 0
15  sysfs                   /sys                    sysfs   defaults        0 0
等价于:
[root ~]# cat -n  /etc/fstab|sed  -n '1,7d;1~2p'
等价于:
[root ~]# cat -n  /etc/fstab|sed   '1,7d' | sed -n  '1~2p'

3.a \在匹配的行后添加内容

实现将root用户的命令历史添加执行时间

[root ~]# sed -i '$a \export HISTTIMEFORMAT="`date "+%T"`"' /root/.bashrc
        #在/root/.bashrc的最后一行添加一条变量

4.正则匹配

关闭第3步的命令历史时间功能

[root ~]# sed -i '/.*HISTTIMEFORMAT.*/d' /root/.bashrc 
        # 注意-i 会直接修改源文件,事先备份

5.s///查找替换

实现将文本的4,8行加注释#

root ~]# sed -i.bak '2,5s/.*/#&/g' /etc/fstab
       #注意这里的&是后向引用的用法

6.读入文件并追加

将创建好的hosts文件内容,追加到/etc/hosts文件后
[root ~]# sed '$r hosts' /etc/hosts

7.匹配的信息另存为,也即写入文件

实现将/var/log/messages中关于网卡信息的分离至eth.log中
[root ~]# sed -n -r   '/eth[0-9]?/w eth.log' /var/log/messages

8.!取反

实现清除所有的#注释信息行

[root ~]# sed -n '/^#/!p' /etc/fstab
等价于
[root ~]# sed '/^#/d' /etc/fstab