在部署openstack的过程中,会接触到大量的sed命令,比如
  
    
  # Bind MySQL service to all network interfaces.
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf
  
   那么这条命令是什么意思?接下来介绍sed命令答案自然就揭晓了。
  
  
   二、sed简介
  
  
   sed:是一个编辑器,是一个强大的
   
    文件处理
   
   工具。
  
  
   sed作用:
   
    用来替换、删除,更新文件中的内容
   
   。sed能自动处理一个或多个文件。
  
  
   sed原理:sed以
   
    文本的行为单位
   
   进行处理,一次处理一行内容。首先sed把当前处理的行存储在临时缓冲区中(称为模式空间pattern space),接着处理缓冲区中的行,处理完成后,把缓冲区的内容送往屏幕。sed处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示,这样不断的重复,直到文件末尾。处理完文件的最后一行后,sed便结束运行。
  
  
   
    
     因为sed是对
     
      
       文件中每行在
      
     
     临时缓冲区中的
     
      副本
     
     进行编辑,所以
    
   
   
    
     原文件内容并没有改变
    
   
   ,除非重定向输出。
  
  
   三、sed命令介绍
  
  
   #sed [-nefri][命令]
  
  
   
    
     参数说明:
    
   
  
  
   -i:
   
    直接
    
     修改
    
    文件,终端不输出结果
   
   。
  
  
   
    -n:使用安静(slient)模式,
    
     取消默认输出
    
    。sed默认会将所有来自stdin的数据输出到终端上。但如果加上-n参数后,不自动打印处理后的结果,只是默默的处理,只有经过sed特殊处理的那一行才被列出来。
   
  
  
   -e: --expression
   
    直接在命令模式上进行sed的动作编辑
   
   。sed -e '...' -e '...' -e '...'
  
  
   -f:指定sed脚本的文件名。
  
  
   -r:sed动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
  
  
   
    
     命令说明:[n1][n2]命令
    
   
  
  
   n1,n2:表示行号,该参数可选,一般表示
   
    希望操作的行数
   
   ,可以是数字,正则表达式或二者混合。
  
  
   用逗号分隔的两个行数表示这两行为起止的行的范围。如1,3表示1,2,3行,美元符号($)表示最后一行。如何没有指定地址,sed将处理输入文件的所有行。地址通常的写法有:n;n,m;n,$。举例,如果我的操作是需要在3到5行之间进行的,则【3,5,[动作行为]】。
  
  
   
    
     a
    
   
   :新增,在当前行的
   
    下一行
   
   追加一行文本。
  
  
   
    
     i
    
   
   :插入,在当前行的
   
    上一行
   
   插入一行文本。
  
  
   
    
     c
    
   
   
    :替换,
   
   以行为单位进行替换,c的后面可以跟字符串,用这些字符串取代n1,n2之间的行。
  
  
   
    
     
      d
     
    
    :删除,
   
   从模式空间删除一行。
  
  
   
    
     p
    
   
   :打印,打印模式空间的行。通常p会与参数【-n】一起使用。
  
  
   
    
     
      s
     
    
   
   
    :
   
   
    替换,
   
   
    通常s命令可以搭配正则表达式
   
   !
   
    例如1,20s/old/new/g。
   
  
  
   下面我们拿Emilia的Big Big World中的部分歌词文件song.txt举例,其内容如下:
  
  $ cat song.txt
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   1、
   
    
     s
    
   
   替换命令
  
  
   将song.txt文件中每行的第一个big替换为small:
  
  
   sed '
   
    
     s
    
   
   /big/small/'
   
    song.txt
   
  
  
   
    解释:s:替换命令,/big/:匹配big字符串,/small/:把匹配替换成small。
   
  
  $ sed 's/big/small/' song.txt
I'm a small big girl
In a small big world
It's not a small big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   将song.txt文件中每行所有的big替换为small:
  
  
   sed '
   
    
     s
    
   
   /big/small/
   
    
     g
    
   
   '
   
    song.txt
   
  
  
   
    
     解释:同上,/g表示一行上替换所有的匹配
    
   
  
  $ sed 's/big/small/g' song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   
    
     Note
    
   
   :这里也可以使用 sed 's
   
    
     #
    
   
   big
   
    
     #
    
   
   small
   
    
     #
    
   
   g' song.txt  ,
   
    紧跟s命令的符号都会被认为是查找串和替换串之间的分隔符
   
   ,这里使用#,其实无论什么字符串(换行符,反斜线除外),只要紧跟s命令,就成了新的串分隔符。
  
  
   将song.txt文件中每行第2个big替换为small: sed '
   
    
     s
    
   
   /big/small/
   
    
     2
    
   
   ' song.txt
  
  
   
    
     解释:/2表示指定一行中第2个匹配的字段操作
    
   
  
  $ sed 's/big/small/2' song.txt 
I'm a big small girl
In a big small world
It's not a big small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   2、
   
    
     -i
    
   
   参数直接修改文件内容
  
  
   上面的sed命令没有改变
   
    song.txt
   
   ,只是把处理后的内容输出,如果要写回文件,可以使用重定向。
  
  $ sed 's\big\small\g' song.txt >song.bak
  
   或使用
   
    -i
   
   直接修改文件内容:sed
   
    
     
      -i
     
    
    's\big\small\g' song.txt
   
  
  $ sed -i 's\big\small\g' song.txt 
$ cat song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   sed 的[-i]参数可以直接修改文件内容,该功能非常有用!
  
  
   举例来说,如果有一个100万行的文件,要在第100行加某些文字。此时使用vim可能会疯掉!因为文件太大了打不开!但是通过sed直接修改/取代的功能,根本不需要打开文件就能完成任务。和vim相比sed就像会魔术一样,vim要打开文件-操作文件-关闭文件,sed直接隔空就对文件操作了,非常方便。
  
  
   正因为sed -i 功能强大,可以直接修改原始文件,也是个危险的动作,需小心使用。
  
  
   3、
   
    
     -e
    
   
   参数编辑命令,进行多行匹配
  
  
   -e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作都将应用到模式缓冲区中的行上。因为是逐行进行多重编辑(即每个命令都在模式空间的当前行上执行),所以
   
    编辑命令的顺序会影响结果
   
   。
  
  
   如果我们要一次替换多个模式,
  
  
   sed "1,3s/big/small/g; 4,5s/do/don't/g" song.txt
  
  
   解释:第一个模式:把第一行到第三行的big替换成small;第二个模式:把第四行到第五行的do替换成don't。
  
  $ sed "1,3s/big/small/g; 4,5s/do/don't/g" song.txt
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I don't don't feel
that I don't don't will miss you much
Miss you much
  
   上面的命令等价于:sed
   
    
     -e
    
   
   "1,3s/big/small/g"
   
    
     -e
    
   
   "4,5s/do/don't/g" song.txt
  
  $ sed  -e "1,3s/big/small/g" -e "4,5s/do/don't/g" song.txt  
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I don't don't feel
that I don't don't will miss you much
Miss you much
  
   4、删除命令
   
    
     d
    
   
   :删除匹配的行
  
  
   命令d删除匹配的输入行,sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间的内容显示在屏幕上。如果是命令d,当前模式空间里的输入行会被删除,不被显示。
  
  
   利用匹配删除行
  
  
   删除song.txt文件中第一次包含“Miss”的行 :sed '/
   
    
     Miss
    
   
   /
   
    
     d
    
   
   ' song.txt
  
  $ sed '/Miss/d' song.txt 
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
  
   下面是利用行号删除行的例子
  
  
   删除song.txt文件中的第1行:sed '
   
    
     1
    
    
     d
    
   
   ' song.txt
  
  $ sed '1d' song.txt 
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   删除song.txt文件中2到5行:sed
   
    '
    
     2,5
    
   
   
    
     d
    
   
   ' song.txt
  
  $ sed '2,5d' song.txt   
I'm a big big girl
Miss you much
  
   删除song.txt文件中第3行之后的行:sed '
   
    
     3
    
    ,
    
     
      $
     
    
   
   
    
     d
    
   
   ' song.txt
  
  $ sed '3,$d' song.txt 
I'm a big big girl
In a big big world
  
   正则匹配可以和行号一起使用,举一个openstack部署中的例子:
  
  
   删除第一次包含“eth2”的行到最后所有的行:
   
    sed
    
     -i
     
      '/eth2/
      
       
        ,
       
      
      $d'
      
       /etc
       
        /network
        
         /interfaces
        
       
      
     
    
   
  
  
   5、插入命令
   
    
     a
    
   
   ,在当前
   
    行后
   
   追加一行
  
  
   a添加新文本到文件中当前行(即读入模式空间中的行)的后面。
  
  
   在song.txt文件中第3行后插入一行并直接作用于song.txt:sed '3
   
    
     a
    
   
   AAAAAAAAAAAAAAAAAAAAAAA' song.txt 【用空格作为分隔符】
  
  $ sed -i '3a AAAAAAAAAAAAAAAAAAAAAAA' song.txt 
$ cat song.txt
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
AAAAAAAAAAAAAAAAAAAAAAA
But I do do feel
that I do do will miss you much
Miss you much
  
   在匹配'Miss'的行后插入一行:sed '/Miss/
   
    
     a
    
   
   AAAAAAAAAAAAAAAAAAAAAAAAAA' song.txt 【用空格作为分隔符】
  
  $ sed '/Miss/a AAAAAAAAAAAAAAAAAAAAAAAAAA' song.txt                                
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
AAAAAAAAAAAAAAAAAAAAAAAAAA
  
   在song.txt最后插入一行:sed '
   
    
     $
    
   
   a append line' song.txt
  
  $ sed '$a append line' song.txt 
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
append line
  
   6、插入命令
   
    
     i
    
   
   ,在当前
   
    行前
   
   插入一行
  
  
   i添加新文本到文件中当前行(即读入模式空间中的行)的前面。
  
  
   在song.txt文件中第3行后插入一行:sed '3
   
    
     i
    
   
   #iiiiiiiiiiiiiiiiiiiiiiiiiii' song.txt  【#作为分隔符】
  
  $ sed '3i#iiiiiiiiiiiiiiiiiiiiiiiiiii' song.txt                
I'm a small small girl
In a small small world
iiiiiiiiiiiiiiiiiiiiiiiiiii
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   在song.txt文件中匹配'Miss'的行前面插入一行:sed '/Miss/
   
    
     i
    
   
   iiiiiiiiiiiiiii' song.txt【空格作为分隔符】
  
  $ sed '/Miss/i iiiiiiiiiiiiiii' song.txt                           
I'm a small small girl
In a small small world
It's not a small small thing if you leave me
But I do do feel
that I do do will miss you much
iiiiiiiiiiiiiii
Miss you much
  
   7、新增多行(
   
    
     i
    
   
   行前插入,
   
    
     a
    
   
   行后追加,其他地方一样,以
   
    
     a
    
   
   为例)
  
  
   插入相同的行,在第2行到第5行之后均插入一行:sed '2,5
   
    
     a
    
   
   append one line ' song.txt
  
  $ sed '2,5a append one line ' song.txt 
I'm a big big girl
In a big big world
append one line 
It's not a big big thing if you leave me
append one line 
But I do do feel
append one line 
that I do do will miss you much
append one line 
Miss you much
  
   插入不同的行,以
   
    
     \n
    
   
   换行
  
  
   在第2行后面插入三行:sed '2
   
    
     a
    
   
   append one line
   
    
     \n
    
   
   append two line
   
    
     \n
    
   
   append three line' song.txt
  
  liuxiaoyan@development:~/mytest$ sed '2a append one line \nappend two line \nappend three line' song.txt   
I'm a big big girl
In a big big world
append one line 
append two line 
append three line
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
  
   8、
   
    
     c
    
   
   命令以行为单位替换
  
  
   把第2到第5行的内容替换为2-5content:sed '2,5
   
    
     c
    
   
   2-5content' song.txt
  
  $ sed '2,5c 2-5content' song.txt 
I'm a big big girl
2-5content
Miss you much
  
   9、
   
    
     p
    
   
   命令显示模式空间的内容
  
  
   以行为单位显示,
  
  
   显示song.txt文件中的第2到第5行: sed
   
    
     -n
    
   
   '2,5
   
    
     p
    
   
   ' song.txt
  
  $ sed -n '2,5p' song.txt 
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
  
   搜索匹配显示:
  
  
   显示匹配'Miss'的行:sed
   
    
     -n
    
   
   '/Miss/
   
    
     p
    
   
   ' song.txt
  
  $ sed -n '/Miss/p' song.txt 
Miss you much
  
   10、
   
    
     -n
    
   
   参数
   
    取消默认输出
   
  
  
   上面的p命令显示时,用到-n参数,因为sed默认把输入行打印在屏幕上:sed '/Miss/p' song.txt
  
  liuxiaoyan@development:~/mytest$ sed '/Miss/p' song.txt    
I'm a big big girl
In a big big world
It's not a big big thing if you leave me
But I do do feel
that I do do will miss you much
Miss you much
Miss you much
  
   所以要打印选定内容,用
   
    
     -n
    
   
   配合p来使用。
  
  
   五、简单正则表达式
  
  
   ^:行首定位符。
  
  
   $:行尾定位符。
  
  
   \<:词首定位符。
  
  
   \>:词尾定位符。
  
  
   .:匹配除换行以外的单个字符。
  
  
   *:匹配0个或多个前导字符。
  
  
   []:匹配字符集合里的任一字符。
  
  
   [^] :匹配不在指定字符集合里的任一字符。
  
  
   更深入了解可参考以下资料:
  
  
   
    《shell基础十二篇》
   
  
  
   
    sed 简明教程- 酷壳陈皓
   
  
  
   
    如果觉得本文对您有帮助~可以
    
     支付宝(左)或
    
    微信支持一下:
   
  
  
   
    看到小伙伴打赏时给我写一些鼓励的话,真的非常感动,谢谢你们。
   
  
  
   
    我开了个微信公众号(
    
     第三个二维码
    
    )用来分享自己的职场英语相关学习经验,感兴趣可以关注,我会不断更新~