Это известное ( 1 , 2 , 3 , 4 , 5 , 6 ) ограничение реализации GNU tr
.
Это не так много, что он не поддерживает иностранные , не английские или не ASCII символы, но он не поддерживает многобайтовые символы.
Эти символы кириллицы будут обрабатываться нормально, если они записаны в наборе символов iso8859-5 (однобайтовый на символ) (а ваша локаль использовала этот набор символов), но ваша проблема заключается в том, что вы используете UTF-8, где не-ASCII символы кодируются в 2 или более байтов.
У GNU есть план (см. Также ), чтобы исправить это, и работа ведется, но еще не началась.
FreeBSD или Solaris tr
не имеют проблемы.
В то же время, в большинстве случаев tr
вы можете использовать GNU sed или GNU awk, которые поддерживают многобайтовые символы.
Например, ваш:
tr -cs '[[:alpha:][:space:]]' ' '
может быть написано:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
или:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Чтобы преобразовать нижний и верхний регистр ( tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
( l
это строчная L
, а не 1
цифра).
или:
gawk '{print tolower($0)}'
Для мобильности perl
есть еще одна альтернатива:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Если вы знаете, что данные могут быть представлены в однобайтовом наборе символов, вы можете обработать их в этой кодировке:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8