Конвертировать UTF8 текст в консоли в верхний или нижний регистр
На днях натолкнулся на одну пренипреятную вещь:
В конвеере понадобилось сконвертировать весь русский текст в UTF8 в нижний регистр.
"Проще простого!" - думаю я.
Даю простую и отработанную годами команду:
$ echo "йцуЙЦУqweQWE" | tr [:upper:] [:lower:]
И получаю:
йцуЙЦУqweqwe
Моему изумлению не было предела! И это во времена повсеместного UTF8!
Сразу уточню: у меня стоит последняя coreutils 8.14 с включенными флагами "nls" и "unicode" (gentoo)
Почесал репу и думаю: "Ну ладно tr, но тот же bash должен понимать UTF8?!"
Пробую:
$ export a="йцуЙЦУqweQWE" $ echo ${a,,}
И получаю ровно то же самое, что и в прошлый раз!
"Хорошо! - завелся я - а что скажет мой любимый sed?"
$ echo "йцуЙЦУqweQWE" | sed 's/.*/\L&/'
Получаю:
йцуйцуqweqwe
Уф! Можно выдохнуть, все работает как ожидалось изначально.
Стало любопытно: а кто же еще не понимает UTF8 в наше время?
Вот что получилось:
$ echo "йцуЙЦУqweQWE" | awk '{ print tolower($0) }' йцуйцуqweqwe $ echo "йцуЙЦУqweQWE" | perl -e 'print lc <>;' йцуЙЦУqweqwe $ echo "йцуЙЦУqweQWE" | dd conv=lcase йцуЙЦУqweqwe 0+1 записей считано 0+1 записей написано скопировано 19 байт (19 B), 2,1229e-05 c, 895 kB/c
Вот так вот! awk не отстает от sed-а, а вот perl разочаровал.
Ну а dd, вроде как, и не должен многобайтные кодировки понимать - не его это задача, просто из спортивного интереса попробовал.
Замечу, что все вышепреведенные команды, отлично отрабатывают свою задачу на английском тексте (т.е. во всех типах кодировок входящий в первый байт).
Аналоги для верхнего регистра будут:
$ echo "йцуЙЦУqweQWE" | tr [:lower:] [:upper:] йцуЙЦУQWEQWE $ export a="йцуЙЦУqweQWE" ; echo ${a^^} йцуЙЦУQWEQWE $ echo "йцуЙЦУqweQWE" | sed 's/.*/\U&/' ЙЦУЙЦУQWEQWE $ echo "йцуЙЦУqweQWE" | awk '{ print toupper($0) }' ЙЦУЙЦУQWEQWE $ echo "йцуЙЦУqweQWE" | perl -e 'print uc <>;' йцуЙЦУQWEQWE $ echo "йцуЙЦУqweQWE" | dd conv=ucase йцуЙЦУQWEQWE 0+1 записей считано 0+1 записей написано скопировано 19 байт (19 B), 2,1229e-05 c, 895 kB/c