Что происходит в следующем фрагменте кода? Я не получаю ожидаемый результат.
Я бы подумал, что это ошибка, но это происходит для 2 разных программ (uniq и sort), поэтому я подозреваю, что это как-то связано ... ну, я не знаю, что ... отсюда вопрос.
Первые 3 (из 4) примеров работают, но четвертый не помогает!
Я ожидал бы того же поведения для всех без исключения персонажей.
то есть. распечатать 2 строки (из 3 строк ввода) ... но в 4-м случае я получаю только 1 строку (для обоих sort -u
и uniq
); две одинаковые линии просто исчезают!
Я преобразовал вывод '\ n' в пространство для компактности вида.
Я использую uniq и сортирую из (GNU coreutils) 7.4 ... работающий на рабочем столе Ubuntu 10.04.3 LTS.
Сценарий:
{
locale -k LC_COLLATE
echo
for c1 in x 〼 ;do
for c2 in z 〇 ;do
echo -n "asis : "; echo -e "$c1\n$c2\n$c2" |tr '\n' ' ';echo
echo -n "uniq : "; echo -e "$c1\n$c2\n$c2" |uniq |tr '\n' ' ';echo
echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
echo
done
echo
done
}
Выход:
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"
asis : x z z
uniq : x z
sort -u: x z
asis : x 〇 〇
uniq : x 〇
sort -u: 〇 x
asis : 〼 z z
uniq : 〼 z
sort -u: 〼 z
asis : 〼 〇 〇
uniq : 〼
sort -u: 〼
# In the last example (of 4) where did the '〇' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#
sort
в одиночку (без опции -u ) ... не сжимает символы .. Что входит, выходит ... Однако, как и ожидал Гиллес, объяснение "экзотических" символов Юникода, имеющих одинаковое каноническое значение , эти символы не сортируются, за исключением того, что они выводятся как несортированная группа FIFO в «верх» вывода сортировки ... Таким образом, здесь действительно есть две проблемы: 1. Символы сортируются не так, как могло бы быть «наивно». «ожидается», и 2. «уникальная» особенность обоихsort
иuniq
потери данных (в некоторых случаях).sort -u
иuniq
отлично работает с:LC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u
(или|uniq
)Ответы:
Короткая версия: сортировка не работает в утилитах командной строки.
Более длинная версия: основная функция для сравнения двух строк
strcoll
. Описание не очень полезно, но концептуальный метод работы состоит в том, чтобы преобразовать обе строки в каноническую форму, а затем сравнить две канонические формы. Функцияstrxfrm
строит эту каноническую форму.Давайте рассмотрим канонические формы нескольких строк (с GNU libc, под Debian squeeze):
Как видите, 〼 и 〇 имеют одинаковую каноническую форму. Я думаю, что это потому, что эти символы не упоминаются в таблицах сопоставления
en_US.UTF-8
локали. Они, однако, присутствуют в японском языке.Исходный код для данных локали (в Debian squeeze) находится в
/usr/share/i18n/locales/en_US
том числе/usr/share/i18n/locales/iso14651_t1_common
. В этом файле нет записи дляU3007
илиU303C
, и при этом они не включены ни в один диапазон, который я могу найти.Я не знаком с правилами построения порядка сортировки , но насколько я понимаю, соответствующие формулировки
Похоже, вместо этого Glibc игнорирует символы, которые не указаны. Я не знаю, есть ли недостаток в моем понимании спецификации POSIX, если я что-то пропустил в определении локали Glibc, или есть ошибка в компиляторе локали Glibc.
источник
charmaps/UTF-8
ничего не говорит о сопоставлении, этоlocales/en_US
важно. Первое правилоLC_COLLATE
: не используйтеLC_COLLATE
. В языковом стандарте C (= POSIX) параметры сортировки являются разумными (строго на основе числовых значений символов).LC_COLLATE=C
... спасибо ...Чтобы "безопасно" использовать
sort
строки Unicode, возможно, взгляните наmsort
:http://www.billposer.org/Software/msort.html
источник
msort
. Опциональный графический интерфейс немного облегчает знакомство с тем, что предлагается. Возможность скопировать сгенерированную команду очень удобна ... И да, она сортирует символы Юникода, но (разве вы просто не любите эти "buts":) ... но у нее нет уникальной опции: (... как упоминалось в ссылке, которую вы разместили:Capabilities of GNU sort and BSD sort lacking in msort are the ability to merge files without sorting them (the --merge option) and the ability to emit only the first of an equal run (the --unique option)
... Хотя сортировка работает :)