tr 命令中的点有什么作用: tr .........AZ A-ZA-Z < "JVPQBOV" (有 13 个点)

tr 命令中的点有什么作用: tr .........AZ A-ZA-Z < "JVPQBOV" (有 13 个点)

我想用tr做一些 rot13 转换。我可以很好地理解这个命令:

tr A-Za-z N-ZA-Mn-za-m <<< "URYC ZR CYRNFR"

哪个输出是HELP ME PLEASE,但我无法弄清楚另一个命令如何产生相同的 rot13 转换:

tr .............A-Z A-ZA-Z <<< "URYC ZR CYRNFR"

所以我有两个问题:

  1. 第二个命令背后的魔力是什么tr
  2. 如何使第二个命令适用于小写和大写,就像第一个命令一样?

答案1

其工作原理如下:

SET1-> .............ABCDEFGHIJKLMNOPQRSTUVWXYZ
SET2-> ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM

所以tr将翻译SET1SET2.

这相当于第一个,因为它也按13单位移动,因为有 13 个点。

要包含小写字母,您必须SET1以类似的偏移量排列它们,即:

.............ABCDEFGHIJKLMNOPQRSTUVWXYZ..........................abcdefghijklmnopqrstuvwxyz

ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklm

Z和之间有 26 个点a,跨越了一半大写字母和一半小写字母。所以tr命令本身将是:

tr .............A-Z..........................a-z A-ZA-Za-za-z

答案2

正如 @Prvt_Yadv 在他们的回答中所说,它有效是因为有 13 个点。

集合是

First set:  .............ABCDEFGHIJKLMNOPQRSTUVWXYZ
Second set: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ

点不是特殊字符,因此如果您的输入中有点,它也会被翻译。在我拥有的版本中tr,它是第二组中的最后一个对应字符,在本例中是M

$ echo URYC ZR CYRNFR. | tr .............A-Z A-ZA-Z
HELP ME PLEASEM

(我可以想象 的不同版本tr可能会使用集合 2 中的第一个匹配字符,这将给出一个A。)

回答你的第二个问题,您需要第一组中另外 13 个点来“用完”第二组中剩余的大写字母:

First set:  .............ABCDEFGHIJKLMNOPQRSTUVWXYZ.............
Second set: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ

然后你可以重复该模式:

First set:  .............ABCDEFGHIJKLMNOPQRSTUVWXYZ..........................abcdefghijklmnopqrstuvwxyz
Second set: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

这给了我们:

tr .............A-Z..........................a-z A-ZA-Za-za-z

所以:

$ echo Uryc zr cyrnfr | tr .............A-Z..........................a-z A-ZA-Za-za-z
Help me please

就我个人而言,我认为您问题中的第一种方法更简单!

第一种方法也不转换输入中的任何其他字符。例如,比较:

$ echo Uryc zr cyrnfr. | tr .............A-Z..........................a-z A-ZA-Za-za-z  
Help me pleasem

$ echo Uryc zr cyrnfr. | tr A-Za-z N-ZA-Mn-za-m
Help me please.

答案3

好的,感谢@Prvt_Yadv,我能够理解这些点。这是第一个问题的答案:

第二个命令背后的魔力是什么tr

这 13 个点只是映射到第二组中的前 13 个字母。所以

tr .............A-Z A-ZA-Z将产生以下集合:

SET1 -> .............ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ

如果您的输入不包含点,您可以丢弃初始序列,因为您不会使用这些替换。那么这些集合将变成:

SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> NOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ

但由于第一组已经包含所有 26 个字母,而第二组有重复的尾随字母,这些也被丢弃,最终变成

SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> NOPQRSTUVXWYZABCDEFGHIJKLM

这是 rot13 替换,与第一个命令相同(除了这里不处理小写字母)。同样的逻辑可以应用于问题的标题:

tr ...A-Z A-ZA-Z <<< “JVPQBOV”将产生以下集合:

SET1 -> ...ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ

丢弃初始序列和尾随重复字母,它们变成:

SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> DEFGHIJKLMNOPQRSTUVXWYZABC

这是 rot3 替换。

现在来说第二个问题:

如何使第二个命令适用于小写和大写,就像第一个命令一样?

为了让它发挥作用,你可以在开头放置所需数量的点,将你的 rot 和 26 个点匹配到上部序列和下部序列之间,就像这样:

tr ........A-Z..........................a-z A-ZA-Za-za-z

这将成功创建一个不敏感的 rot8。为了直观地理解为什么这是有效的,让我们看看这些集合:

SET1 -> ........ABCDEFGHIJKLMNOPQRSTUVXWYZ..........................abcdefghijklmnopqrstuvxwyz
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZabcdefghijklmnopqrstuvxwyzabcdefghijklmnopqrstuvxwyz

排除点映射和尾随字母:

SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZabcdefghijklmnopqrstuvxwyz
SET2 -> IJKLMNOPQRSTUVXWYZABCDEFGHijklmnopqrstuvxwyzabcdefgh

现在它适用于大写和小写:)

使其工作的另一种方法是使用tr如下两个命令:

tr .............A-Z A-ZA-Z <<< "ABJ V hqrefgnaq" | tr .............a-z a-za-z

@iruvar 给出了使用点替换的警告:当输入字符串包含点时,此命令将无法按预期工作。这是因为这些点被映射到其他字母,并且在进行替换时,tr会将输入点更改为最后一个映射的字母。但实际上您可以使用点以外的任何其他字符。因此,如果在tr命令中使用点有问题,您可以使用@例如。这同样可以工作:

tr @@@@@@@@@@@@@A-Z A-ZA-Z <<< "GUNAX LBH NYY..."

相关内容