Eu queria usar tr
para substituir caracteres "ilegais" em uma string por um caractere de substituição, onde os caracteres "ilegais" estão todos fora de um conjunto de caracteres "permitidos" (ou seja, são o complemento do conjunto de caracteres permitidos). No entanto, ao usar a -c
opção e o *
especificador de repetição explícito ou a extensão implícita do "conjunto 2", tr
anexa uma instância adicional do caractere de substituição à saída.
Reproduzir
- Sejam os caracteres "permitidos"
a-n
, especificados literalmente comoabcdefghijklmn
. - Deixe o caractere de substituição ser
z
. - Deixe a string de entrada ser
hell
ouhello
. A string de saída esperada é entãohell
ehellz
, respectivamente.
Demonstração
Caracteres ilegais presentes, extensão implícita do conjunto 2
$ echo "hello" | tr -c 'abcdefghijklmn' 'z' hellzz
A saída esperada é
hellz
.Somente caracteres permitidos presentes, extensão implícita do conjunto 2
$ echo "hell" | tr -c 'abcdefghijklmn' 'z' hellz
A saída esperada é
hell
.Caracteres ilegais presentes, extensão explícita do conjunto 2
$ echo "hello" | tr -c 'abcdefghijklmn' '[z*]' hellzz
A saída esperada é
hellz
.Somente caracteres permitidos presentes, extensão explícita do conjunto 2
$ echo "hell" | tr -c 'abcdefghijklmn' '[z*]' hellz
A saída esperada é
hell
.O mesmo acontece quando eu uso uma string here em vez de echo-pipe (na verdade, a string here foi a construção que usei quando me deparei com esse efeito pela primeira vez):
$ tr -c 'abcdefghijkl' '[z*]' <<< "hello" hellzz
Por que tr
acrescenta um adicional z
aqui?
Isso está no Linux, com bash, localidade UTF-8 e tr
no GNU coreutils 8.25 e 8.30.