15、sed 翻译命令 y

假设我们有一行文本如下

门口吊刀,刀倒吊着

如果我们要将它变成

门口刀悬,悬倒刀着

要如何转变呢?

替换命令 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