Почему в сортировке отображается нечисловая запись после «0»?

8

Я хочу отсортировать файлы по номеру в имени файла. Вот файлы:

$ ls *.f
0.f  13.f  1.f  22.f  4.f  abc.f

Результат сортировки:

$ ls *.f | sort -t. -k1n
0.f
abc.f # note this file!
1.f
4.f
13.f
22.f

То, что я ожидал, было:

$ ls *.f | sort -t. -k1n
abc.f
0.f
1.f
4.f
13.f
22.f

Почему abc.fпоказали сразу после 0.fи до 1.f? Это потому что 0не рассматривается как число sort? Я искал в Интернете и не нашел никаких ссылок.

nn0p
источник
Все то же самое после добавления LC_ALL=C.
nn0p

Ответы:

12

Причина в том, что при использовании числовой сортировки строки без чисел рассматриваются как ноль. Сортировка GNU правильно определяет поведение, но не комментирует почему. Справочная страница по иллюминаторам для сортировки SunOS дает объяснение:

-n
Ограничивает ключ сортировки исходной числовой строкой, состоящей из необязательных пустых символов, необязательного знака минус и нуля или более цифр с необязательным разделительным знаком и разделителями тысяч (как определено в текущей локали), который сортируется по арифметическому значению , Пустая строка цифр рассматривается как ноль. Ведущие нули и знаки нулей не влияют на порядок.

Это поведение также указано в SUSv4 и POSIX.1-2008 ( http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html ), используя то же словоблудие, что и на man-странице illumos.

У сортировки GNU также есть -g«общая числовая сортировка», которая сортирует по числам с плавающей запятой вместо целых, где строки пустых цифр сортируются до нуля. Я не уверен, является ли это побочным эффектом или намеренным. Тем не менее, -gприходит с предупреждением, так как это значительно медленнее, чем -n. Если вы сортируете большой набор данных или делаете что-то, чего ждут пользователи, вам следует избегать -g.

bahamat
источник
Для полноты следует также упомянуть, как обстоят дела sortс двумя строками, имеющими одинаковый ключ.
kasperd
1

Вы можете использовать -g

-g, --general-numeric-sort сравнить по общему числовому значению

root@virt01-ubuntu:~# ls  | sort -t. -k1g
a.txt
0.txt
1.txt
2.txt
3.txt
root@virt01-ubuntu:~#
rɑːdʒɑ
источник