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

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

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

/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/ 
  • Как найти / исправить ошибку в пути
  • Показывать материал под подсказкой в ​​командной строке?
  • XTerm не обновляет изменения vim должным образом
  • Как я могу обнаружить оболочку без входа? (В Zsh)
  • Как я могу определить, контролируется ли оболочка из SSH?
  • Проблема с пониманием привязок ключей
  • Поиск файлов в ZSH не работает
  • Есть ли способ показать только несанкционированные строки в текстовом файле / скрипте?
  • Как я могу связать poweroff с git push?
  • Использование вложенного тройного выражения в командной строке .zshrc
  • Что означает «следовая ловушка», когда сообщается zsh?
  • Interesting Posts

    Как я могу обрабатывать очереди?

    Запуск комбинации клавиш vim при запуске

    Если вы запускаете автоматические обновления

    Почему crontab не хранится в домашних каталогах пользователей?

    Правила iptables для двух разных контейнеров lxc

    chmod не работает с папками «d – – —»

    Как ядро ​​Linux знает, какой процесс вызвал системный вызов?

    Использование sed для поиска и замены сложной строки (желательно с регулярным выражением)

    Сравните файлы и переименуйте, если содержимое отличается

    Сколько уровней таблицы страниц использует ядро ​​Linux? 4 или 5?

    Каковы последствия увеличения жестких и мягких ограничений для пользователя ldap

    Как запустить интерактивный скрипт в трубке CUPS?

    Как и когда можно было бы считывать данные с последовательного устройства через команду cat?

    Установка git "sudo: apt-get: команда не найдена"

    Не удалось восстановить потерянный логин

    Linux и Unix - лучшая ОС в мире.