Вопрос или проблема
Сценарий:
# на Linux
$ cat r456.txt
e+e+l
e+e-c
$ cat r456.txt | sort
e+e-c
e+e+l
$ sort --version
sort (GNU coreutils) 8.30
# на Cygwin
$ cat r456.txt
e+e+l
e+e-c
$ cat r456.txt | sort
e+e+l
e+e-c
$ sort --version
sort (GNU coreutils) 9.0
Упаковано Cygwin (9.0-1)
Здесь мы видим, что sort
на Linux и на Cygwin возвращает разные результаты. Почему?
Как сделать так, чтобы sort
на Linux и на Cygwin возвращали одинаковые результаты?
UPD. Локали:
# на Linux
$ 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=
# на Cygwin
$ locale
LANG=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_ALL=
UPD2. Я изменил все локали на Cygwin на en_US.UTF-8
. Тем не менее, sort
все еще возвращает разные результаты:
# на Linux
$ cat r456a.txt
u1
u-1
$ cat r456a.txt | sort
u-1
u1
# на Cygwin
$ cat r456a.txt
u1
u-1
$ cat r456a.txt | sort
u1
u-1
$ locale
LANG=en_US.UTF-8
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_ALL=en_US.UTF-8
Как это исправить?
UPD3. Наблюдение: как на Linux, так и на Windows все переменные LC
установлены на en_US.UTF-8
, строки для сортировки:
ProfileDataContainer.cpp
ProfileData.cpp
Linux sort
сортирует их как
ProfileDataContainer.cpp
ProfileData.cpp
Cygwin sort
сортирует их как
ProfileData.cpp
ProfileDataContainer.cpp
Это ошибка в sort
на Linux или в sort
на Cygwin?
Как сделать так, чтобы sort
на Linux давал те же результаты, что и sort
на Cygwin?
Версии: Linux sort
: 8.32, Cygwin sort
: 9.0. Оба являются GNU coreutils
.
Ответ или решение
Различия в работе команды sort
между Linux и Cygwin могут возникать по нескольким причинам, связанным с локализацией (locale) и версией утилиты.
Причины различий
-
Локаль (Locale):
При выполнении сортировки, поведение командыsort
может зависеть от установленной локали. В вашем случае на Linux вы только что указали, что используете локальen_US.UTF-8
, тогда как в Cygwin сначала использовалиC.UTF-8
, а затем изменили наen_US.UTF-8
. Тем не менее, если локали все еще работают по-разному, это может быть связано с разными интерпретациями символов под разными локалями.Важно проверить не только переменную
LANG
, но и другие переменные LC (например,LC_COLLATE
), которые могут влиять на порядок сортировки. -
Версии GNU coreutils:
Вы заметили, что версияsort
в Linux (8.30) отличается от версии в Cygwin (9.0). Между версиями могли произойти изменения в реализации алгоритмов сортировки, что может также объяснять разницу в поведении. В версии 9.0 могли быть внесены улучшения или исправления, которые изменили поведение алгоритмов, поэтому поведение на Cygwin может отличаться от поведения в Linux с более ранней версией. -
Порядок символов:
Разные системы могут иметь различные правила сортировки для специфичных символов (например,+
,-
). Поскольку поведениеsort
может основываться на правилах сортировки, определенных в используемой локали, это тоже может объяснять разницу в результатах.
Решение проблемы
Чтобы добиться одинаковых результатов на обеих системах, попробуйте выполнить следующие шаги:
-
Убедитесь, что на обеих системах установлена одна и та же локаль. Для этого на Cygwin выполните:
export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8
Также убедитесь, что
LC_COLLATE
установлена правильно. -
Попробуйте указать явное использование стандартной локали с помощью параметра
--help
, чтобы Cygwin реализовал сортировку в стандартном варианте:LC_COLLATE=C sort файл.txt
-
Если проблема сохраняется, возможно, стоит проверить и изменить порядок сортировки путем явного определения сравнения. Например, можно использовать ключи
-V
или-d
, если они подходят вам.
Заключение
Различия в сортировке на разных системах могут быть вызваны локализацией и версиями утилит. Установите одинаковые параметры локализации и протестируйте с разными версиями GNU coreutils. После внесения необходимых изменений поведение sort
должно стать единообразным на обеих платформах.