27、sed 字符串替换命令 s

「查找并替换 」 操作在任何文本编辑器中都很常见。

如果缺少了 替换 功能的话,那 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