Usando o comando tr com intervalos de caracteres

1

Nos últimos meses, tenho aprendido sobre a linha de comando com a ajuda da Linha de Comando Linux de William E. Shotts. A linha de comando do Linux continua sendo um livro popular para iniciantes que gostariam de aprender mais sobre a linha de comando do Linux.

Em um dos capítulos, ele introduz o comando tr . O livro diz que os conjuntos de caracteres podem ser construídos de uma das três maneiras: uma lista enumerada como ABCDEFGHIJKLMNOPQRSTUVWXYZ ; um intervalo de caracteres, como A-Z ; e classes de caracteres POSIX, como [:upper:] .

A parte que não entendo é quando o livro diz ao leitor para ser cauteloso sobre o uso de intervalos de caracteres para o conjunto de caracteres por causa da ordem de agrupamento de localidade e sugere que o leitor use classes de caracteres POSIX.

Eu pessoalmente nunca encontrei um problema usando intervalos de caracteres como A-Z com

echo "lowercase letters" | tr a-z A-Z

então por que eu deveria evitar o uso de intervalos de caracteres em favor de classes de caracteres POSIX?

Caso você esteja se perguntando, minha localidade é en_US.UTF-8.

    
por John_Patrick_Mason 09.11.2017 / 02:36

1 resposta

1

Você está usando o UTF-8. Yay! ASCII, e por extensão UTF-8 (porque o pessoal da UTF tentou torná-lo um superconjunto de ASCII), tem os alfabetos em ordem alfabética sem intervalos, então a-z contém todos os caracteres minúsculos normais e nada mais, e assim por diante .

No entanto, isso não precisa ser verdade em alguma outra codificação. O exemplo clássico é EBCDIC :

  

As lacunas entre as letras fizeram com que o código simples que funcionava em ASCII falhasse   EBCDIC. Por exemplo, for (c='A';c<='Z';++c) configuraria c para o 26   letras no alfabeto ASCII, mas 40 caracteres incluindo um número de   não atribuídos em EBCDIC. Corrigindo isto requer complicando o código   com chamadas de função que foi muito resistido por programadores.

Eu gostaria de pensar que ninguém usa coisas estranhas como essa, mas quem sabe?

O GNU tr não suporta Unicode, AFAIK, mas para programas que possuem, [[:upper:]] também corresponderia a caracteres Unicode considerados alfabetos maiúsculos, por exemplo, um "A" de largura total ou um A com um sotaque : À.

$ printf "%s\n" A a A À | grep '[[:upper:]]'
A
A
À
$ printf "%s\n" A a A À | grep '[A-Z]'   # I'm also using Unicode, so grep tries to be friendly
A
À
$ printf "%s\n" A a A À | LC_ALL=C grep '[A-Z]'
A 
    
por muru 09.11.2017 / 02:54