Почему сортировка в Linux и Cygwin возвращает разные результаты?

Вопрос или проблема

Сценарий:

# на 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) и версией утилиты.

Причины различий

  1. Локаль (Locale):
    При выполнении сортировки, поведение команды sort может зависеть от установленной локали. В вашем случае на Linux вы только что указали, что используете локаль en_US.UTF-8, тогда как в Cygwin сначала использовали C.UTF-8, а затем изменили на en_US.UTF-8. Тем не менее, если локали все еще работают по-разному, это может быть связано с разными интерпретациями символов под разными локалями.

    Важно проверить не только переменную LANG, но и другие переменные LC (например, LC_COLLATE), которые могут влиять на порядок сортировки.

  2. Версии GNU coreutils:
    Вы заметили, что версия sort в Linux (8.30) отличается от версии в Cygwin (9.0). Между версиями могли произойти изменения в реализации алгоритмов сортировки, что может также объяснять разницу в поведении. В версии 9.0 могли быть внесены улучшения или исправления, которые изменили поведение алгоритмов, поэтому поведение на Cygwin может отличаться от поведения в Linux с более ранней версией.

  3. Порядок символов:
    Разные системы могут иметь различные правила сортировки для специфичных символов (например, +, -). Поскольку поведение sort может основываться на правилах сортировки, определенных в используемой локали, это тоже может объяснять разницу в результатах.

Решение проблемы

Чтобы добиться одинаковых результатов на обеих системах, попробуйте выполнить следующие шаги:

  1. Убедитесь, что на обеих системах установлена одна и та же локаль. Для этого на Cygwin выполните:

    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8

    Также убедитесь, что LC_COLLATE установлена правильно.

  2. Попробуйте указать явное использование стандартной локали с помощью параметра --help, чтобы Cygwin реализовал сортировку в стандартном варианте:

    LC_COLLATE=C sort файл.txt
  3. Если проблема сохраняется, возможно, стоит проверить и изменить порядок сортировки путем явного определения сравнения. Например, можно использовать ключи -V или -d, если они подходят вам.

Заключение

Различия в сортировке на разных системах могут быть вызваны локализацией и версиями утилит. Установите одинаковые параметры локализации и протестируйте с разными версиями GNU coreutils. После внесения необходимых изменений поведение sort должно стать единообразным на обеих платформах.

Оцените материал
Добавить комментарий

Капча загружается...