Подтвердить что ты не робот

Unix-сортировка символов подчеркивания

У меня есть две Linux-машины, на которых тип unix ведет себя по-другому. Я считаю, что я сузил его до обработки символа подчеркивания.

Если я запустил sort tmp, где tmp содержит следующие две строки:

aa_d_hh
aa_dh_ey

один выход машины

aa_d_hh
aa_dh_ey

(то есть "_" предшествует "h" ), в то время как другие выходы

aa_dh_ey
aa_d_hh

(т.е. "h" предшествует "_" ). Мне нужно, чтобы эти машины вели себя вместе (поскольку я использую sort -m позже, чтобы объединить очень большие файлы).

Можно ли каким-либо образом заставить сортировку вести себя так или иначе?

Спасибо.

4b9b3361

Ответ 1

Вы можете установить LC_COLLATE в традиционный порядок сортировки только для вашей команды:

env LC_COLLATE=C sort tmp

Это не изменит текущую среду, только ту, в которой выполняется команда sort. У вас должно быть такое же поведение.

Ответ 2

порядок сортировки зависит от текущего значения переменной среды LC_COLLATE. Проверьте свою локальную документацию на "locale", "setlocale" и т.д. Установите LC_COLLATE в "POSIX" на обеих машинах, и результаты должны совпадать.

Ответ 3

Разница связана с вашим locale. Используйте команду locale, чтобы проверить текущие настройки.

Существует несколько различных категорий локалей, таких как LC_COLLATE, LC_TIME и LC_MESSAGES. Вы можете изменить их все, установив переменную окружения LC_ALL или LANG или только порядок сортировки (сортировки), установив переменную окружения LC_COLLATE. Локаль C или POSIX - это базовая локаль, определенная стандартом; другие включают en_US (US English), fr_FR (французский) и т.д.

Ответ 4

Вероятно, это связано с различием в локали. В локали en_US.UTF-8 подчеркивание (_) сортируется после букв и цифр, тогда как в POSIX C локали они сортируются после прописных букв и цифр, но перед строчными номерами.

# won't change LC_COLLATE=C after execution
$ LC_COLLATE=C sort filename

Вы также можете использовать sort --debug, чтобы показать дополнительную информацию о поведении сортировки в целом:

$ (echo 'foo_bar'; echo 'fooAbar'; echo 'foo0bar'; echo 'fooabar') |
      LC_COLLATE=en_US.UTF-8 sort --debug
sort: using ‘en_US.UTF-8’ sorting rules
foo0bar
fooabar
fooAbar
foo_bar

$ (echo 'foo_bar'; echo 'fooAbar'; echo 'foo0bar'; echo 'fooabar') | 
      LC_COLLATE=C sort --debug
sort: using simple byte comparison
foo0bar
fooAbar
foo_bar
fooabar

Как также показано в этом ответе, вы можете использовать приведенную выше формулу для принудительного LC_COLLATE=C для одной команды без изменения среды оболочки: