我想用tr
替换字符替换字符串中的“非法”字符,其中“非法”字符全部位于一组“允许”字符之外(即它们是允许字符集的补集)。但是,当使用该-c
选项以及显式*
重复说明符或“set 2”的隐式扩展时,tr
会将替换字符的附加实例附加到输出。
重现
- 令“允许”的字符为
a-n
,按字面指定为abcdefghijklmn
。 - 令替换字符为
z
。 - 让输入字符串为
hell
或hello
。预期的输出字符串分别是 thenhell
和hellz
。
示范
存在非法字符,隐式集 2 扩展
$ echo "hello" | tr -c 'abcdefghijklmn' 'z' hellzz
预期输出是
hellz
.仅允许存在字符,隐式集 2 扩展
$ echo "hell" | tr -c 'abcdefghijklmn' 'z' hellz
预期输出是
hell
.存在非法字符,显式设置 2 扩展名
$ echo "hello" | tr -c 'abcdefghijklmn' '[z*]' hellzz
预期输出是
hellz
.只允许存在字符,显式设置 2 扩展名
$ echo "hell" | tr -c 'abcdefghijklmn' '[z*]' hellz
预期输出是
hell
.当我使用here-string而不是echo-pipe时,也会发生同样的情况(实际上,here-string是我第一次偶然发现这种效果时使用的构造):
$ tr -c 'abcdefghijkl' '[z*]' <<< "hello" hellzz
为什么这里要tr
追加一个呢?z
这是在 Linux 上,使用 bash、UTF-8 语言环境,并且tr
来自 GNU coreutils 8.25 和 8.30。