Удалить все, кроме самого большого файла определенного типа

Я пытаюсь организовать обложку альбома в своей музыкальной коллекции, так что каждому папке присваивается только одно изображение.

Моя структура каталогов в настоящее время выглядит так:

/path/to/music/Album Name/ /path/to/music/Album Name/1 - Track one.flac ... /path/to/music/Album Name/cover.jpg (either this) /path/to/music/Album Name/folder.jpg (or this) /path/to/music/Album Name/Album Name.jpg (or this is the largest file) /path/to/music/Album Name/AlbumArtSmall.jpg 

(плюс другие изображения с низким разрешением, созданные медиа-проигрывателем Windows)

Я хотел бы просканировать каждую папку и удалить все, кроме самого большого jpg, и переименовать ее в cover.jpg .

Как указывают теги, я установил cygwin, но могу также загрузиться в Ubuntu, где у меня есть доступ к bash и zsh, если это облегчает задачу.

3 Solutions collect form web for “Удалить все, кроме самого большого файла определенного типа”

В zsh (который вы можете использовать с Cygwin или Linux), вы можете использовать квалификаторы glob для выбора самого большого файла. Это самый большой размер файла по размеру байта, а не с точки зрения размеров изображения, что, вероятно, здесь правильно, так как оно позволяет получать изображения с высоким разрешением.

 for d in /path/to/music/**/*(/); do rm -f $d/*.jpg(oL[1,-2]N) mv $d/*.jpg $d/cover.jpg done 

Цикл перемещает все поддиректории /path/to/music рекурсивно. Суффикс (/) ограничивает соответствие каталогов. Аргумент rm -f использует три классификатора glob: oL для сортировки по размеру; [1,-2] чтобы сохранить только совпадения до следующего-последнего ( PATTERN([-1]) является последним совпадением, PATTERN([-2]) является совпадением следующего дня и PATTERN([1,-2]) – список совпадений от первого до следующего-последнего включительно); и N чтобы создать пустой список, а не оставить шаблон нерасширенным или сообщить об ошибке, если шаблон не соответствует файлу.

Вы можете получить безобидную ошибку, если оставшийся файл уже называется cover.jpg или если в каталоге нет файла .jpg . Чтобы избежать их, измените вызов mv на

 [[ -e $d/cover.jpg ]] || mv $d/*.jpg $d/cover.jpg 

Вот альтернативный метод, который сначала переименовывает, а затем удаляет. Он использует синтаксис PATTERN1~PATTERN2 , для которого требуется опция extended_glob , для выбора файлов, которые соответствуют PATTERN1 но не PATTERN2 . ((#jpgs)) если массив jpgs содержит хотя бы один элемент.

 setopt extended_glob for d in /path/to/music/**/*(/); do jpgs=($d/*.jpg(oL)) ((#jpgs)) || continue [[ $jpgs[1] == */cover.jpg ]] || mv $jpgs[1] $d/cover.jpg rm -f $jpgs[2,-1] done 

Вот вам Шварцское преобразование :

 stat -c "%s %n" *.jpg | sort -n | cut -d " " -f 2- | head -n -1 | while IFS= read -r filename; do echo rm "$filename"; done 

Используйте stat для вывода размера и имени файла, сортировки, удаления поля размера, игнорирования самого большого и повторения полученных файлов.

Использование GNU find.

 #!/usr/bin/env bash # GNU find + bash4 / ksh93v / zsh # Get the largest file matching pattern in the given directories recursively ${ZSH_VERSION+false} || emulate ksh ${BASH_VERSION+shopt -s lastpipe extglob} function getLargest { typeset -A cur top || return typeset dir x for dir in "$2"/*/; do [[ -d $dir ]] || return 0 getLargest "$1" "${dir%/}" || return top[size]=-1 find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | { while :; do for x in cur\[{size,name}\]; do IFS= read -rd '' "$x" || break 2 done if (( cur[size] > top[size] )); then top[size]=${cur[size]} top[name]=${cur[name]} fi done mv -- "${dir}"{"${top[name]}",cover.jpg} rm -f -- "${dir}"!(cover.jpg) } done } # main pattern dir [ dir ... ] function main { if [[ -n $1 ]]; then typeset dir pattern=$1 shift for dir; do [[ -d $dir ]] || return getLargest "$pattern" "$dir" done else return 1 fi } main \*.jpg /path/to/music/ 
  • Как получить полное завершение в диалоговом окне запуска приложения?
  • Команда ведет себя по-разному при сохранении в файле * .sh
  • Проблемы с использованием возвышенного текста для редактирования командной строки в режиме ВП
  • Задание zsh для ssh сбивает имена хостов с локальными файлами
  • Zsh: завершение каталога хеширования
  • таблица ключевых привязок?
  • Как сообщить остальной системе, что моя оболочка изменилась с zsh на bash?
  • история показывает только текущую сессию
  • Ctrl + левая / правая стрелка
  • Обновление zsh на красной шляпе 5 x86_64
  • zshell - это вкладка, дополняющая двусмысленные варианты
  • Linux и Unix - лучшая ОС в мире.