sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

命令的格式

1
2
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

第一种是将对行的操作命令放在命令中,这种比较常见。第二种是将对行的命令独立放在一个文本文件中。 选项部分常用有:

  • -n,用来控制是打印全部的行,还是只打印受影响的行。
  • -i,默认的sed处理的文件都无法影响到文件本身。使用这个选项可以编辑文件本身,等同于将命令的输出再重定向到本文件。文件的内容为去掉-i之后命令的输出内容。

命令部分的写法

sed命令最难理解的就是’’之间的内容,也就是对行的操作命令。操作命令的基本格式就是,操作行范围+对行上的操作,具体表示如下:

1
[n1,[n2]]function

范围表示如下:

  • n1和n2部分指定本条命令需要处理的哪些行,n1表示开始行,n2表示结束行。
  • 如果没有n1,n2的话就表示处理全部行。
  • 也可以只有n1,用来特质某行。
  • 可以直接通过数字指定。比如2,5就是第2行到第5行。
  • 用$可以表示最后行,比如2,$d就表示删除第2到最后一行
  • 范围不一定时连续的一些行,也可以时满足条件的一些行,比如sed '/^test/'d file 删除所有test开始行
  • 也可以用正则表达式来表示满足条件的行,比如 sed -n '5,/^test/p' file

常用的操作有如下:

  • a 插入内容,在当前行下面插入文本,后面跟要插入的内容
  • i 插入内容,在当前行上面插入文本
  • c 替换,把选定的行改为新的文本
  • d 删除
  • p 打印
  • s 替换,使用正则表达式替换行内的特定字符。

不同的参数后面还可以跟不同的具体内容,用来表示操作的参数。比如,a新增行可以跟需要新增的内容,d删除就没啥跟的。

s替换命令

s命令用正则表达式来替换行内的内容,基本格式s/s1/s2/s3常规的用法就不说了,这里记录下一些强大的用法。

  • (..) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers
  • & 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**
  • 使用后缀 /g 标记会替换每一行中的所有匹配,当需要从第N处匹配开始替换时,可以使用 /Ng。

& 主要用在命令的s2部分,利用s1匹配到的内容。在s1匹配到时就调用s2的部分进行替换。比如:正则表达式 \w\+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词:

1
2
echo this is a test line | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]

所有以192.168.0.1开头的行都会被替换成它自已加localhost:

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

子串匹配标记\1

s1部分需要用括号来表示一个子串,括号内所匹配的内容就是一个子串的内容,子串有编号。在s2部分使用\1,\2等来引用子串的内容。

1
2
echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
this is 7 in a number

命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,\(..\) 用于匹配子串,对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2

参考资料

1. 一篇很详细的使用示例