Jest to znane ( 1 , 2 , 3 , 4 , 5 , 6 ) ograniczenie implementacji GNU tr
.
Nie chodzi o to, że nie obsługuje znaków obcych , nieanglojęzycznych ani ASCII, ale nie obsługuje znaków wielobajtowych.
Te znaki cyrylicy byłyby traktowane OK, gdyby zostały zapisane w zestawie znaków iso8859-5 (jednobajtowy na znak) (a twoje ustawienia regionalne używały tego zestawu znaków), ale twoim problemem jest to, że używasz UTF-8, gdy nie jest to ASCII znaki są zakodowane w 2 lub więcej bajtach.
GNU ma plan (patrz także ), aby to naprawić, a prace są w toku, ale jeszcze ich nie ma.
FreeBSD lub Solaris tr
nie mają problemu.
Tymczasem dla większości przypadków użycia tr
możesz użyć GNU sed lub GNU awk, które obsługują znaki wielobajtowe.
Na przykład:
tr -cs '[[:alpha:][:space:]]' ' '
można napisać:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
lub:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Aby przekonwertować małe i wielkie litery ( tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
(to l
jest mała litera L
, a nie 1
cyfra).
lub:
gawk '{print tolower($0)}'
Przenośność perl
to kolejna alternatywa:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Jeśli wiesz, że dane mogą być reprezentowane w jednobajtowym zestawie znaków, możesz przetworzyć je w tym zestawie znaków:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8