Как в Linux выполняется сортировка имён файлов?

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

MiK13
Сообщения: 1289
ОС: Linux Debian

Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

Столкнулся со странной проблемой.
У племянника на внешнем диске (NTFS) куча самой разной музыки.
Когда был линуксе, он попросил поставить послушать 21-ю сонату Шуберта. Там 4 части. Они находились в подкаталоге S21. В mc я видел, что все 4 файла (4 части) идут по порядку. И запустил их просто командой mpv *
Через некоторое время он спрашивает: "А почему нет первой части?" Я смотрю -- действительно идёт воспроизведение 2-й, а потом 3-й части.
Захожу через другое окно терминала в этот же каталог и выдаю

Код: Выделить всё

mik139@MDD49:/media/mik139/ANDREW_500_1/- МУЗЫКА -/- ШУБЕРТ -/Schubert - Piano Sonatas (Wilhelm Kempff)/S21$ ls -l
итого 101568
-rwxrwxrwx 3 mik139 mik139 22302345 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - II. Andante sostenuto.mp3
-rwxrwxrwx 3 mik139 mik139 11516908 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - III. Scherzo (Allegro vivace).mp3
-rwxrwxrwx 3 mik139 mik139 50809251 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - I. Molto moderato.mp3
-rwxrwxrwx 3 mik139 mik139 19371406 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - IV. Allegro ma non troppo.mp3
mik139@MDD49:/media/mik139/ANDREW_500_1/- МУЗЫКА -/- ШУБЕРТ -/Schubert - Piano Sonatas (Wilhelm Kempff)/S21$ ls -lU
итого 101568
-rwxrwxrwx 3 mik139 mik139 50809251 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - I. Molto moderato.mp3
-rwxrwxrwx 3 mik139 mik139 22302345 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - II. Andante sostenuto.mp3
-rwxrwxrwx 3 mik139 mik139 11516908 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - III. Scherzo (Allegro vivace).mp3
-rwxrwxrwx 3 mik139 mik139 19371406 май  8  2014 Piano Sonata No.21 in B-dur, D.960 - IV. Allegro ma non troppo.mp3
Проблема в том, что номера частей обозначены не арабскими, а римскими цифрами: I, II, III, IV.
Я привык, что ls по умолчанию сортирует по имени. Но какой критерий сравнения?
Для проверки создал 4 файла с простыми именами. И вот что получил:

Код: Выделить всё

mik139@MDD49:/dev/shm/A$ ls -lU I.M.mp3 II.A.mp3 III.S.mp3 IV.A.mp3 
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 I.M.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 II.A.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 III.S.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 IV.A.mp3
mik139@MDD49:/dev/shm/A$ ls -l I.M.mp3 II.A.mp3 III.S.mp3 IV.A.mp3 
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 II.A.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 III.S.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 I.M.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 IV.A.mp3
Причём, если я переименовываю I.M в I.A, то порядок получается верным:

Код: Выделить всё

mik139@MDD49:/dev/shm/A$ ls -l I.A.mp3 II.A.mp3 III.S.mp3 IV.A.mp3 
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 I.A.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 II.A.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 III.S.mp3
-rw-r--r-- 1 mik139 mik139 0 авг 31 00:29 IV.A.mp3
То, что "II" идёт после "I.", а "III" после "II." понятно -- код 'I' больше кода точки.
Но почему "I.M" идёт ПОСЛЕ "III.S"? При том, что в окне mc файлы всегда располагаются в "правильном" порядке (по возрастанию номеров,, выраженных римскими цифрами).
Пока писал этот пост,, решил провести ещё один эксперимент. Последовательно переименовывать файл I.?.mp3, ставя на место 3-го знака последовательно все буквы от A до Z. И посмотреть, что будет выдавать команда ls -l.
Результат получился такой. Для букв [A-H] ls ставит имя этого файла на первое место, для букв [I-U] -- на третье место, а для букв [V-Z] -- на четвёртое. Как это объяснить?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21430
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение Bizdelnick »

Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

Проведя ещё пару экспериментов, понял, что mc сортирует имена файлов в порядке возрастания их значений, а вот ls, как и sort, сначала сравнивает только буквы, а при совпадении смотрит ещё и на то, что между буквами может находиться. Причём, значения этих знаков больше, чем букв.
Спасибо сказали:
Аватара пользователя
yoricI
Сообщения: 2977
ОС: gentoo fluxbox

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение yoricI »

Поведение mc вроде регулируется в настройках.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21430
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение Bizdelnick »

Порядок сортировки зависит от локали (а именно LC_COLLATE). Строго лексикографический порядок будет при LC_COLLATE=C или LC_COLLATE=C.UTF-8.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

Bizdelnick писал:
01.09.2018 10:44
Порядок сортировки зависит от локали (а именно LC_COLLATE). Строго лексикографический порядок будет при LC_COLLATE=C или LC_COLLATE=C.UTF-8.
Спасибо. Буду знать. И использовать.
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение s.xbatob »

На самом деле имена файлов никак не сортируются, readdir() их выдаёт в произвольном порядке. Более того, они состоят не из символов, а из произвольных байт (хотя два кода имеют особое значение), которые в символы могут ещё и не преобразоваться. Вся сортировка -- это инициатива программ, выводящих их списки. Поэтому и результаты разные. Особенно если программа начинает проявлять интеллект, например правильно сортировать числа. Тут уже и правильный LC_COLLATE не поможет, нужен лексический разбор.
Так что лучше ничей интеллект не испытывать, а именовать файлы так, чтобы они сортировались однозначно: 01 - Piano Sonata...
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21430
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение Bizdelnick »

s.xbatob писал:
02.09.2018 10:27
имена файлов никак не сортируются, readdir() их выдаёт в произвольном порядке.
Ну только не в произвольном, а в том, в каком они записаны в каталоге.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

MiK13 писал:
02.09.2018 01:47
Bizdelnick писал:
01.09.2018 10:44
Порядок сортировки зависит от локали (а именно LC_COLLATE). Строго лексикографический порядок будет при LC_COLLATE=C или LC_COLLATE=C.UTF-8.
Спасибо. Буду знать. И использовать.
Попробовал. И показалось, что проблема решена:

Код: Выделить всё

mik13@mik13:/dev/shm/b$ ls -1
II.A.mp3
III.S.mp3
I.M.mp3
IV.A.mp3
mik13@mik13:/dev/shm/b$ LC_COLLATE=C ls -1
I.M.mp3
II.A.mp3
III.S.mp3
IV.A.mp3
Программа sort, кстати, сортирует точно также.
Но основная проблема была не в этом, а в том, чтобы заставить плеер проигрывать файлы в нужном порядке. А вот это не проходит:

Код: Выделить всё

mik13@mik13:/dev/shm/b$ echo *.mp3
II.A.mp3 III.S.mp3 I.M.mp3 IV.A.mp3
mik13@mik13:/dev/shm/b$ LC_COLLATE=C echo *.mp3
II.A.mp3 III.S.mp3 I.M.mp3 IV.A.mp3
Конечно, задача не является неразрешимой. Я файлы проигрываю, запуская их из mc. И тут это задача решается просто: выделить все файлы и запустить их командой mpv %u. В командную строку они попадут в том порядке, в котором их видит mc
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21430
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение Bizdelnick »

LC_COLLATE=C sh -c 'echo *.mp3'
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение s.xbatob »

Bizdelnick писал:
04.09.2018 16:41
LC_COLLATE=C sh -c 'echo *.mp3'
НЕ ВЫЙДЕТ! требуется "правильная" сортировка чисел, да ещё записанных римскими цифрами.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21430
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение Bizdelnick »

s.xbatob писал:
04.09.2018 16:55
НЕ ВЫЙДЕТ! требуется "правильная" сортировка чисел, да ещё записанных римскими цифрами.
Ясен пень, правильно сортировать числа он не начнёт, я просто показал, как ТСу добиться сортировки в лексикографическом порядке при использовании *.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

Bizdelnick писал:
04.09.2018 16:41
LC_COLLATE=C sh -c 'echo *.mp3'
Спасибо. Получилось. По крайней мере с echo. Думаю, что и с mpv пройдёт.

Как я понял, LC_COLLATE=C надо установить для самого шела, так как именно он сортирует файлы в *
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Как в Linux выполняется сортировка имён файлов?

Сообщение MiK13 »

s.xbatob писал:
04.09.2018 16:55
НЕ ВЫЙДЕТ! требуется "правильная" сортировка чисел, да ещё записанных римскими цифрами.
Понятно, что в целом для чисел, записанных "по римски" не выйдет, так как код цифры 10 (X) больше кода цифры 50 (L), а код цифры 100 (C) ещё меньше (хотя, если записывать не латинскими буквами, а римскими цифрами, исключая Ⅺ и Ⅻ, то должно пройти, но надо проверить).
Но в данном случае это нужно было для правильного порядка проигрывания частей музыкального произведения, а их очень редко бывает больше четырёх. А до 9 (включая VIII) должно пройти.
Спасибо сказали: