Страницы

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

пятница, 7 февраля 2020 г.

Как отсортировать текстовый список файлов по расширению?

#linux #bash


Есть файл log.txt. В этом файле содержится громадный список файлов и расширений,
где каждое новое название начинается с новой строчки, приблизительно вот так:

1.jpg
common.pdf
script.sh
Justin Bieber - Baby.mp3


Нужно перекинуть весь список в еще один файл, в котором список файлов будет упорядочен
по расширению.
    


Ответы

Ответ 1



можно, например, воспользоваться программой sort, передав ей две опции: указание использовать в качестве разделителя полей точку: -t. указание сортировать по второму полю: -k 2 $ sort -t. -k 2 исходный-файл > отсортированный-файл уточнения: так называемые «расширения» файла пришли к нам из файловой системы fat16 (а в неё — из файловой системы для операционной системы cp/m), где это были отдельные сущности. с тех пор данное понятие присутствует лишь по традиции и довольно условно. в операционных системах же системах unix и их «наследниках» (bsd, gnu и т.п.) этого понятия не существовало изначально: имя файла, например, file.tar.gz, — это цельная сущность, в ней нет никаких «расширений». да, строку .tar.gz можно считать «суффиксом» в имени файла. или даже двумя суффиксами: tar и gz. потому мой ответ и содержит предложение выделить в имени файла первую точку, подразумевая, что после неё и находится суффикс имени файла, или, в традиционно-устаревшей терминологии — «расширение». если же всё-таки требуется сортировка по самому последнему суффиксу в имени файла, т.е., чтобы файл с именем a.z.a был раньше файла с именем a.b, то можно, например, воспользоваться такой конструкцией (она будет корректно работать при наличии любых символов в исходном файле, и вертикальной черты, и символа табуляции): $ rev исходный-файл | sed -r 's/^([^.]+).*/&\t\1/' | rev | sort | cut -f 2- > отсортированный-файл

Ответ 2



Можно ввести временное поле с расширением файла, отсортировать по нему, а затем удалить это поле. Пример: $ while read F; do printf '%s|%s\n' "$(echo "$F" | sed 's|.*\.\([a-zA-Z0-9]\+\)$|\1|')" "$F"; done

Ответ 3



Можно вытащить расширение с помощью awk (переменная $NF хранит последнее поле - т.е. расширение), прилепить его к началу каждой строки, отсортировать нормальным образом и затем удалить лишнее из начала строки: awk -F. '{ printf "%s\t%s\n", $NF, $0 }' file | sort | cut -f2-

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

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