Questa è una limitazione nota ( 1 , 2 , 3 , 4 , 5 , 6 ) dell'implementazione GNU di tr
.
Non è tanto che non supporta caratteri stranieri , non inglesi o non ASCII, ma che non supporta caratteri multibyte.
Quei caratteri cirillici sarebbero trattati OK, se scritti nel set di caratteri iso8859-5 (byte singolo per carattere) (e il tuo locale stava usando quel set di caratteri), ma il tuo problema è che stai usando UTF-8 dove non ASCII i caratteri sono codificati in 2 o più byte.
GNU ha un piano (vedi anche ) per risolverlo e il lavoro è in corso ma non è ancora arrivato .
FreeBSD o Solaris tr
non hanno il problema.
Nel frattempo, per la maggior parte dei casi d'uso di tr
, puoi usare GNU sed o GNU awk che supportano caratteri multi-byte.
Ad esempio, il tuo:
tr -cs '[[:alpha:][:space:]]' ' '
potrebbe essere scritto:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
o:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Per convertire tra lettere minuscole e maiuscole ( tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
(questa l
è una minuscola L
, non la 1
cifra).
o:
gawk '{print tolower($0)}'
Per la portabilità, perl
è un'altra alternativa:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Se sai che i dati possono essere rappresentati in un set di caratteri a byte singolo, puoi elaborarli in quel set di caratteri:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8