Isso é um conhecido ( 1 , 2 , 3 , 4 , 5 , 6 ) limitação da implementação GNU de tr
.
Não é tanto que não ofereça suporte a caracteres estrangeiros , que não estejam em inglês ou não sejam ASCII, mas que eles não suportam caracteres de múltiplos bytes.
Esses caracteres cirílicos seriam tratados como OK, se escritos no conjunto de caracteres iso8859-5 (um byte por caractere) (e sua localidade estava usando esse conjunto de caracteres), mas o problema é que você está usando UTF-8 onde caracteres não-ASCII são codificados em 2 ou mais bytes.
O GNU tem um plano (veja também ) para consertar isso e o trabalho está em andamento, mas ainda não chegou.
FreeBSD ou Solaris tr
não tem o problema.
Nesse meio tempo, para a maioria dos casos de uso de tr
, você pode usar o GNU sed ou o GNU awk que foram internacionalizados.
Por exemplo, o seu:
tr -cs '[[:alpha:][:space:]]' ' '
poderia ser escrito:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
ou:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Para converter entre maiúsculas e minúsculas ( tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
(que l
é uma minúscula L
, não a 1
dígito).
ou:
gawk '{print tolower($0)}'
Para portabilidade, perl
é outra alternativa:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Se você souber que os dados podem ser representados em um conjunto de caracteres de byte único, você poderá processá-los nesse conjunto de caracteres:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8