三剑客之Sed

sed:stream editor(流编辑器)

工作特性:并不直接处理文本文件本身,处理机制为每当处理一个文件的时候,它会逐行读取,每次把一行读取到内存空间中去,而后在模式空间(pattern space)中完成编辑.并把编辑好的结果输出到屏幕上

 功      能:数据替换、删除、增加、等,数据为关键字或者一整行,

模式空间:默认不编辑原文件,仅对模式空间中的数据做处理,处理结束后,把模式空间中的内容输出到屏幕上。

保持空间:在模式空间中处理一行内容会继续处理下一行,那么对于处理过的行可能还有其他处理,因此可以先把处理好的数据存放在hold space 中,然后等到全部处理好之后在回到模式空间中。

用法:

sed [OPTION]... script-only-if-no-other-script} [input-file]...
  script:指明要对指定位置做什么动作
          地址定界编辑命令(中间没有空格)

option:

        -n:不输出模式空间中没被匹配到的内容,被匹配到的内容根据编辑命令决定是否输出

            从文件中读取行然后通过模式进行处理,如果不予给定模式相匹配,那么系统默认会将这些不匹配模式的行输出到屏幕上,n选项的作用就是不显示此类行,对于能匹配到的行,则通过编辑命令来决定是否输出(如:d就直接删除,p为显示)

        – r:支持扩展正则表达式                   

            指定地址定界中使用pattern匹配是使用扩展正则表达式

        -e:多个编辑命令对一个文件进行编辑 

            指定的多个script来处理输入的文本文件

        – f:从文件中读取编辑命令                 

            从文件中读取script来处理输出的文本文件

        – i:直接修改原文件                           

            将更改过的内容保存到原文件

地址定界:指定文本地址进行编辑

空地址:全文处理
#:指定文本中的某一行
/pattern/:被模式匹配到的每一行
#,#:从第几行到第几行
#,+#:从几行开始的向下几行
#,/pattern/:从指定的行到第一次被pattern匹配到的行之间的所有行
1~2:从第一行开始每隔一行      奇数行
2~2:从第二行开始每隔一行      偶数行

编辑命令:对指定的关键字或行进行编辑命令处理

    d:删除模式空间中的内容

1.sed  'd'  sed.txt    //删除全文
2.sed  ‘1d’  sed.txt    //删除第1行
3.sed  ‘/^[[:digit:]]/d'  sed.txt    //删除以数字开头的所有行
4.sed  '1,5d' sed.txt    //删除第1行到第5行
5.sed  '3,+3' sed.txt    //删除第3行及以下的3行(一共删除了4行)
6.sed   '1,/^14/d  sed.txt     //删除第1行到第一次匹配到以数字“14”开头的行之间的所有行
7.sed   '1~2d'  sed.txt    //从第1行开始,每隔1行删除1行(删除2、4、6、8……)显示奇数行
8.sed    '2~2d'  sed.txt    //从第2行开始,每隔1行删除1行(删除1、3、5、7……)显示偶数行

   

    p:打印模式空间中的内容         (显示被指定的地址定界范围所框定的内容,而不是模式空间中的所有内容)

1.sed   '1,3p' sed   //显示第1行到第三行(原有的文件里的会重复显示一次,加上匹配到的第1到3行也会显示)
2.sed  -n  '1,3p' sed   //此时原文件中的行就不会显示来了(n 为不打印原文件中的行,接着被匹配到的行根据编辑命令来决定动作)

    a \test:在指定行后面添加文本行,内容为“\test”,支持使用\n实现多行插入

sed '/^[^[:digit:]]/a  \hello world '   sed.txt     
  //给文件中以非数字开头的所有行的下方添加新行,内容为“hello world”

    i  \test:在指定行前面插入文本行,内容为“\test",支持使用\n实现多行插入  

sed '/^[[:digit:]]/i  \hello world '   sed.txt    
   //给文件中以数字开头的所有行的上方添加新行,内容为“hello world”

    c \test:把匹配到的行替换成为此处指定的文本内容"\test"(整行替换)              

sed '/^[[:digit:]]/c \hello world' sed.txt     
   //把文件中所有以数字开头的行内容覆盖为指定的内容“hello world”

    w /path/to/somefile:保存模式空间中匹配到的行至指定文件中                         

  sed ’/^#/w /testdir/#.txt  sed.txt  
    //将文件中以#号开头的行另存到 (/testdir/#.txt)文件中。

    s  /path/from/somefile:读取指定文件中的内容到当前模式指定的行后面         

  sed '1r /etc/issue' sed.txt     
    //将/etc/issue文件中的内容读取到sed.txt文件中的第1行后面

=:为模式匹配到的行打印行号  

    sed  '/^#/='  sed.txt     //给sed.txt文件首行为#号开头的行在其上方添加行号

!:条件取反                           

sed  '/^[[:digit:]]/!d'  sed.txt    //删除sed.txt文件中不以数字开头的行

s/pattern/string/修饰符:查找替换(默认只替换每一行中第一次被模式匹配到的字符串)

 将每一行当中能被模式匹配到的字符串替换成string字符串

sed 's@[[:digit:]]@AAA@g' sed     //将sed.txt文件中的数字全局替换成为字符”AAA“

    其中: 1.“@”符为分割符,可任意更改分隔符,但三个分割符必须为一致

        第1个@与第2个@之间的内容为地址定界,(就是我们需要替换的原内容)
        第2个@与第3个@之间的内容为转换内容,(将前面需要替换的内容更改为此处的内容)
        第3个@符后面的为修饰符,用于更改系统默认的一些操作

      2、history | sed -r 's@^[[:space:]]+@@'
         //将history列表中的行首为一个空格字符以上字符不显示(最后两个@@中间没有内容,就代表空,就表示把前面的替换成空,就相当于删除行首的空格字符)

            修饰符(替换标记):加修饰符更改默认操作

               g:全局替换

                    系统默认是只操作每一行的首次匹配到的字符,如果一行后面还有符合条件的就不在执行。在最后一个@紧跟g,则表示全局符合条件的都执行操作。

                i:查找时忽略字符

            当我们在查找某字母时用的是小写,然则我们要把这些字母转换为其他的字符或字母,如果我们指定的字母为小写,那么系统默认只更改小写字母。

                     如果加上“ i  ”,则不区分大小写,只要同字母就都执行

              w:将替换成功的结果保存到指定的文件中

          history | sed -r 's@^[[:space:]]+@#@w sed.txt2'       
                //  将转换成功的结果保存到sed.txt2文件中

              & 已匹配字符串标记(调用之前匹配到的字符串,位置任意)

         sed 's/^192.168.0.1/&localhost/' file
        //

示例:  

      1、删除/etc/grub2.conf文件中所有以空白开头的行行首的空白字符                                                    

        [root@localhost test]# sed -r  's/^[[:space:]]+//' /etc/grub.conf

       2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符                  

         sed 's/^#[[:space:]]\+//' /etc/fstab   //此删除符合题目要求
         sed -r 's/^(#|#[[:space:]]+)//' /etc/fstab    //此命令则删除#号没空格的

      3、在/root/install.log每一行行首增加#号                                                                                        

        sed 's/^/#/' /root/install.log

      4、在/etc/fstab文件中不以#开头的行的行首增加#号                                                                         

        sed 's/^[^#]/#/' fstab

      5、处理/etc/fstab路径,使用sed命令取出其目录名和基名                                                                    

基名:echo "/etc/sysconfig/network-scripts/" | sed -r 's@.*/([^/]+)/?@\1@'
目录:1.echo "/etc/sysconfig/network-scripts/" | sed -r 's@[^/]+/?$@@'
      2.echo "/etc/sysconfig/network-scripts/" | sed -r 's@(.*/)[^/]+/?@\1@'

       6、利用sed 取出ifconfig命令中本机的IPv4地址                                                                                

ifconfig | sed '2!d' | sed  -r 's@.*inet.addr:(.*)B.*@\1@'

       7、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数           

ls /mnt/Packages/* | sed -r 's@.*\.(.*)\.rpm$@\1@' | sort | uniq -c

原创文章,作者:Lii,如若转载,请注明出处:http://www.178linux.com/31654