C'est une limitation connue ( 1 , 2 , 3 , 4 , 5 , 6 ) de la mise en oeuvre GNU de tr
.
Ce n'est pas tant qu'il ne prend pas en charge les caractères étrangers , non anglais ou non ASCII, mais qu'il ne prend pas en charge les caractères multi-octets.
Ces caractères cyrilliques seraient traités correctement, s’ils étaient écrits dans le jeu de caractères iso8859-5 (codet sur un octet par caractère) (et que votre paramètre régional utilisait ce jeu de caractères), mais votre problème est que vous utilisez le format UTF-8 où les paramètres non-ASCII sont utilisés. les caractères sont codés sur 2 octets ou plus.
GNU a un plan (voir aussi ) pour résoudre ce problème et le travail est en cours, mais pas encore.
FreeBSD ou Solaris tr
n'ont pas le problème.
En attendant, dans la plupart des cas d'utilisation de tr
, vous pouvez utiliser GNU sed ou GNU awk qui prennent en charge les caractères multi-octets.
Par exemple, votre:
tr -cs '[[:alpha:][:space:]]' ' '
pourrait être écrit:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
ou:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Pour convertir entre les majuscules et les minuscules ( tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
(c'est l
une minuscule L
, pas le 1
chiffre).
ou:
gawk '{print tolower($0)}'
Pour la portabilité, perl
est une autre alternative:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Si vous savez que les données peuvent être représentées dans un jeu de caractères d'un octet, vous pouvez les traiter dans ce jeu de caractères:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8