Почему следующие два примера дают различный порядок сортировки? - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть скрипт, который использует base64, кодирует список имен файлов, а затем сортирует их. По большей части проблема работает именно так, как мне нужно, но я заметил очень странную вещь в сортировке. Следующие два

(for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done)|sort|xargs -d '\n' -n 1 bash -c 'echo -n $(base64 -d<<<"$0")" "';echo

против

(for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done)|LC_ALL=C sort|xargs -d '\n' -n 1 bash -c 'echo -n $(base64 -d<<<"$0")" "';echo

Вы увидите выход первого: «7 1 8 2 9 3 4 5 6», второго - «1 2 3 4 5 6 7 8 9 ".

Моя локаль по умолчанию - en_CA.UTF-8.

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Это проблема локали. Обрезка посторонних битов:

$ echo $LANG
en_US.UTF-8
$ (for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done)|sort
IDcgCg==
IDEgCg==
IDggCg==
IDIgCg==
IDkgCg==
IDMgCg==
IDQgCg==
IDUgCg==
IDYgCg==
$ (for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done)|LC_ALL=C sort
IDEgCg==
IDIgCg==
IDMgCg==
IDQgCg==
IDUgCg==
IDYgCg==
IDcgCg==
IDggCg==
IDkgCg==

(я использую en_US, но en_CA почти такой же; просто извиняюсь больше)

Как видите, использование не C локали делает сортировку без учета регистра, IDcgCg== предшествует IDEgCg==, в то время как при использовании C, наоборот. Вот почему вы видите LC_ALL=C, часто добавляемый перед чем-либо в скрипте, который должен иметь согласованные результаты независимо от локали пользователя.

0 голосов
/ 18 апреля 2020

У меня не такая же проблема, как у вас. Однако сравните

(for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done) | sort

с

(for i in 1 2 3 4 5 6 7 8 9; do base64<<<" $i " ; done) | LC_ALL=C sort

Прописаны ли записи в верхнем / нижнем регистре по-разному?

...