Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

Вывести файлы, отсортировав по числовой составляющей имени

#linux #файлы #bash #сортировка


Есть в папке некоторое колличество файлов:

 pre_1_filea
 pre_2_fileb
 ...
 pre_9_filek
 pre_10_filel
 ...


Их надо вывести отсортировав по числовой составляющей  имени файла. Префикс имени
файлов pre всегда один и тот же для всего набора файлов и может содержать любые допустимые
символы. Разделитель _ может поменяться на - или еще какой другой.

Если пробую так:

 $ ls -1 pre*
 pre_1_filea
 pre_10_filel
 pre_2_fileb
 pre_9_filek


, то файлы отсортированы в алфавитном порядке.

Как отсортировать их по числовой составляющей в имени? 

Пробовал так же с sort -n -t_ -k2, работает, но разделитель не гарантируется и может
также встретиться в префиксе имени pre.
    


Ответы

Ответ 1



Должна подойти сортировка по версии: $ for i in {1,2,9,10}; do touch A2-V411-THZ_${i}_file; done $ ls -1v A2-V411-THZ* A2-V411-THZ_1_file A2-V411-THZ_2_file A2-V411-THZ_9_file A2-V411-THZ_10_file Из мнауала man ls: -v natural sort of (version) numbers within text Здесь подробнее about-version-sort. Можно предварительно проверить, удовлетворяет ли эта сортировка структуре имени файлов: Version-sorted strings are compared such that if ver1 and ver2 are version numbers and prefix and suffix (suffix matching the regular expression ‘(\.[A-Za-z~][A-Za-z0-9~]*)*’) are strings then ver1 < ver2 implies that the name composed of “prefix ver1 suffix” sorts before “prefix ver2 suffix”.

Ответ 2



Очень непрямой подход, но работает. Можно вытащить первое число из имени файла, поставить его перед именем, разделив пробелом, сортировать по числам, и убрать число: sed -n -e 's/[^0-9]*\([0-9]\+\).*/\1 \0/; p' | sort -n | awk '{ print $2 }' Для следующего набора тестовых кейсов работает: pre_1_file pre_9_file 2_file pre8_file pre_foo_bar_3_file pre_10_file Если в префиксе у вас есть числа, решение немного меняется: prefix="A2-V411-THZ" sed -n -e "s/${prefix}[^0-9]*\([0-9]\+\).*/\1 \0/; p" | sort -n | awk '{ print $2 }' Прошу обратить внимание на двойные кавычки в данном случае. Работает верно на таком наборе: A2-V411-THZ_1_file A2-V411-THZ_9_file A2-V411-THZ-2_file A2-V411-THZ8_file A2-V411-THZ_foo_bar_3_file A2-V411-THZ_10_file

Комментариев нет:

Отправить комментарий