「查找并替换 」 操作在任何文本编辑器中都很常见。
如果缺少了 替换 功能的话,那 sed 真的称不上是一款伟大的文本编辑器了。
好在sed 有,而且非常强大。
sed提供了 单字符命令 s 用于实现 替换 功能。
s是 substitution 的缩写,后者翻译为中文是 替换 的意思。
s命令的语法格式如下
[address1[,address2]]s/pattern/replacement/[flags]
- address1 和 address2 分别是 起始地址 和 结束地址,可以是 行号或 模式字符串。
- address1 和 address2 都是可选参数。如果都不填,默认是模式缓冲区的数据。
- pattern 是要查找的模式。
- replacement 是替换后的字符串
- flag 是一些标志,是可选参数,用于改变 替换 的默认行为。
范例
下面的范例中,我们把 简单 替换为 极简。
[www.ddkk.com]$ echo -e "DDKK.COM 弟弟快看,程序员编程资料站,DDKK.COM 弟弟快看,程序员编程资料站" | sed 's/简单/极简/'
运行结果如下
极简教程,DDKK.COM 弟弟快看,程序员编程资料站
咦,答案似乎是我们想要的,但好像又不是我们想要的。
第一个简单 的确替换成 极简 了,可第二个 简单 怎么还在啊?
全局替换标志 g
如果仔细观察上面的范例,你会发现只有第一个 简单 被替换为 极简,第二个 简单 却还在。
为什么呢?
原因很简单,默认模式下
替换只会发生一次,也就是只有第一个搜索到的会被替换掉。
这种替换模式称之为 非贪婪模式。
非贪婪模式 会保证替换尽可能发生但又会保证尽可能少的发生。
为了把所有的出现都替换掉,必须使用 g 标志。
g标志通常称为 全局替换标志。
使用了全局替换标志的替换又称为 贪婪模式。
全局替换标志 g 的语法格式如下
[address1[,address2]]s/search/replacement/g
范例
下面的范例中,我们把所有的 简单 都替换为 极简。
[www.ddkk.com]$ echo -e "DDKK.COM 弟弟快看,程序员编程资料站,DDKK.COM 弟弟快看,程序员编程资料站" | sed 's/简单/极简/g'
运行结果如下
极简教程,极简编程
匹配条件下的文本替换
我们还可以给 替换 添加一个前置条件。
只有当前置条件为真时才执行替换命令。
这个前置,在 sed 中一般为一个模式匹配。语法格式如下
[address1[,address2]]s/[condition pattern]/ s/search/replacement/
范例
下面的范例,只有行数据包含 教程 时才把 简单 替换为 极简。
[www.ddkk.com]$ echo -e "DDKK.COM 弟弟快看,程序员编程资料站\nDDKK.COM 弟弟快看,程序员编程资料站" | sed '/教程/ s/简单/极简/'
运行结果如下
极简教程
DDKK.COM 弟弟快看,程序员编程资料站
指定替换第 n 个出现
sed中的正则表达式比其它工具的正则表达式强大了许多,其中一个突出的功能就是可以 指定替换第 n 个出现。
指定替换第 n 个出现的语法格式如下
[address1[,address2]]s/search/replacement/n
n从 1 开始,比如替换第一次出现则为 1 ,第二次则为 2。
范例
下面的sed 代码,我们指定把第二个 单 替换为 复。
[www.ddkk.com]$ echo "DDKK.COM 弟弟快看,程序员编程资料站,DDKK.COM 弟弟快看,程序员编程资料站" | sed 's/单/复/2'
运行结果如下
DDKK.COM 弟弟快看,程序员编程资料站,简复编程
sed中的正则替换功能远远比我们上面所学强大。它还支持一些 选项 或者说 标志 功能来改变 替换行为。
下面我们就列举几个常见的标志并做一些简单的介绍。
输出数据标志 p
有时候需要在替换之后 立即 输出替换后的内容,这时候就可以使用 p 标志。
其实,你说 p 是一个命令呢还是一个标志呢?哎,说不清楚道不明白。
p标志的使用语法如下
[address1[,address2]]s/search/replacement/p
范例
下面的代码,我们使用 p 标志在替换之后立即输出替换后的内容
[www.ddkk.com]$ echo 'DDKK.COM 弟弟快看,程序员编程资料站 DDKK.COM 弟弟快看,程序员编程资料站' | sed -n 's/简单/极简/p'
运行结果如下
极简教程 DDKK.COM 弟弟快看,程序员编程资料站
保存到其它文件 w 标志
有时候我们需要将改变的行保存到其它文件,这时候可以使用 w 标志。
w标志和我们前面章节中学过的 sed 写文件命令 w 很像。很多时候,我都觉得 w 不是标志而是一个命令。
w标志的使用语法如下
[address1[,address2]]s/search/replacement/w another_file
another_file 是要保存的文件路径
范例
下面的范例演示了如何使用 w 标志,把修改后的内容保存到另一个文件 /tmp/data.txt 中
[www.ddkk.com]$ echo 'DDKK.COM 弟弟快看,程序员编程资料站 DDKK.COM 弟弟快看,程序员编程资料站' | sed 's/简单/极简/w /tmp/data.txt'
运行结果如下
极简教程 DDKK.COM 弟弟快看,程序员编程资料站
打开/tmp/data.txt 可以看到内容如下
[www.ddkk.com]$ cat /tmp/data.txt
极简教程 DDKK.COM 弟弟快看,程序员编程资料站
忽略大小写 i 标志
有时候我们需要 不区分字母大小写的替换。
比如s/i/am/ 既能够替换 im 中的 i,也能够替换 IM 中的 I。
这时候就可以使用 i 标志,i 标示是 ignore 的缩写,翻译为中文为 忽略 的意思。
i标志的使用语法如下
[address1[,address2]]s/search/replacement/i
范例
下面的范例,我们使用 i 标志,将输入行中的所有 i ,不管是 i 还是 I 都替换为 a。
[www.ddkk.com]$ echo -e "I am use a third IM" | sed 's/i/a/ig'
运行结果如下
a am use a thard aM