假设我们有一行文本如下
门口吊刀,刀倒吊着
如果我们要将它变成
门口刀悬,悬倒刀着
要如何转变呢?
替换命令 s ?
肯定不行啊,如果使用替换命令 s 是做不到这一点的,s 命令只能将 吊刀 作为一个整体来替换。
例如下面的命令
[www.ddkk.com]$ echo -e "门口吊刀,刀倒吊着" | sed 's/吊刀/刀悬/'
运行结果如下
门口刀悬,刀倒吊着
第二个刀 和 第二个 吊 都不正确的。
如果使用替换命令 s 单字替换,比如
[www.ddkk.com]$ echo -e "门口吊刀,刀倒吊着" | sed 's/吊/刀/g;s/刀/悬/g'
结果如下
门口悬悬,悬倒悬着
结果也不对啊!
那要怎么办呢?
没办法了嘛?
不着急,我们先来对比下两者的不同
门口吊刀,刀倒吊着
|| | |
vv v v
门口刀悬,悬倒刀着
大家看出什么端倪没有?
这个过程可以堪称,把 门口吊刀,刀倒吊着 从左到右逐字查找,如果发现有 吊 则替换成 刀,如果发现有 刀 则替换成 悬,替换一次之后立即停止开始替换下一个。
我们把这个过程称之为 翻译。因为 transalte。
这种 翻译 过程有一个规律: 查找字和替换字必须一一对应。
如果我们把需要替换的字按照从左到右的顺序放在一起,就是 吊刀,把替换后的字从左到右放在一起,就是 刀悬。
我们把吊刀 和 刀悬 组成的翻译对称之为 字典。
所以,看起来翻译的过程就是查字典替换而已。
sed 中的翻译命令 y
sed为这种 翻译 提供了一个单字母命令 y。
y命令用于根据 字典 逐字翻译文本。
y命令的语法格式如下
[address1[,address2]]y/list-1/list-2/
- address1 和 address2 是 行寻址 的开始行和结束行
- y 是翻译命令
- list-1 和 list-2 就是字典对。且必须是普通文本,不支持正则表达式。
其中 list-1 和 list-2 的长度要一样。否则会报错。
范例
下面的范例,我们使用 y 命令和字典 吊刀 ->` 刀悬 翻译行
[www.ddkk.com]$ echo -e "门口吊刀,刀倒吊着" | sed 'y/吊刀/刀悬/'
运行结果如下
门口刀悬,悬倒刀着
范例2
下面这个范例比范例1清晰多了,也许更能让你理解翻译的过程
[www.ddkk.com]$ echo "1 5 15 20" | sed 'y/151520/IVXVXX/'
运行结果如下
I V IV XX