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