У команді cutє можливість -cпрацювати над символами, а не байтами з цим параметром -b. Але це, схоже, не працює, на en_US.UTF-8мові:
Другий байт дає другий символ ASCII (який закодований точно так само в UTF-8):
$ printf 'ABC' | cut -b 2
B
але не дає другого з трьох грецьких символів, що не належать до ASCII, у мові UTF-8:
$ printf 'αβγ' | cut -b 2
�
Це добре - це другий байт .
Тому ми дивимось на другий символ замість цього:
$ printf 'αβγ' | cut -c 2
�
Це виглядає розбитим.
З деякими експериментами виявляється, що діапазон 3-4показує другий символ:
$ printf 'αβγ' | cut -c 3-4
β
Але це точно так само, як у байтах 3 до 4:
$ printf 'αβγ' | cut -b 3-4
β
Таким чином, -cце не більше, ніж -bдля UTF-8.
Я б очікував, що налаштування місцевості не підходить для UTF-8, але порівняно, wcпрацює як очікувалося;
Він часто використовується для підрахунку байтів, за допомогою параметра -c( --bytes).
(Зверніть увагу на заплутані назви опцій.)
$ printf 'αβγ' | wc -c
6
Але він також може рахувати символи з опцією -m( --chars), яка просто працює:
$ printf 'αβγ' | wc -m
3
Тож моя конфігурація здається нормальною, але щось особливе cut.
Можливо, він взагалі не підтримує UTF-8? Але це, здається, підтримує багатобайтові символи, інакше його не потрібно буде підтримувати -bі -c.
Отже, що не так? І чому?
Наскільки я можу сказати, налаштування локалі виглядає правильно для utf8:
$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Вхід, байт за байтом:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
-c, використовується той же код, що і-b. Ви подивилися на вихідний код? Можливо, ви можете знайти підказку, для чого-cнасправді призначено.