3

У меня есть большое количество (более 400) каталогов, заполненных фотографиями. То, что я хочу сделать, это сохранить большие размеры этих фотографий. В каждом каталоге содержится от 31 до 66 файлов.

В каждом каталоге есть эскизы и более крупные версии, а также файл с именем example.jpg

Я легко отправил файл example.jpg:

rm */example.jpg

Первоначально я думал, что было бы легко удалить миниатюры, но проблема в том, что они не названы последовательно. Типичным рисунком были photo1.jpg и photo1s.jpg . Я сделал rm */photo*s.jpg но в итоге некоторые файлы с именем photoXs.jpg были на самом деле больше, а не меньше. Argh.

Поэтому я хочу просканировать каждый каталог на предмет размера файлов и удалить (или переместить) миниатюры. Сначала я думал, что я просто ls -R каждого файла, извлекаю размер каждого файла и сохраняю их под порогом. Эта проблема? В одном каталоге большой будет 1,1 МБ, а большой палец - 200 КБ. В другой большой 200к и малый 30к.

Хуже того, файлы на самом деле в основном называются photo1.jpg - поэтому простое размещение их всех в одной папке, сортировка по размеру и удаление в группах не будет работать без переименования, и, если это возможно, я бы предпочел сохранить их в их папки.

Я был почти полон решимости сделать все это вручную, но потом решил спросить здесь.

Как бы вы сделали эту задачу?

4 ответа4

4

Если есть какая-то конкретная вырезка, которую вы можете найти, например, все большие изображения размером более 200 КБ, то вы можете сделать это:

find */*.jpg -size -200k -delete

Возможно, вы захотите сделать резервную копию в первую очередь.

3

Если размеры файлов не соответствуют, являются ли размеры изображения?

Вы можете использовать identify , инструмент, который поставляется с ImageMagick, чтобы получить размеры изображения. Через несколько простых сценариев bash вы можете работать с изображениями в зависимости от их размера.

Чтобы получить ширину и высоту изображения с identify:

identify -format '%wx%h' filename

вы получите вывод примерно так:

[john@awesome:~]$ identify -format '%wx%h' W4.JPG
1680x1050

Затем вы можете использовать утилиту cut чтобы получить числа в вашем скрипте:

[john@awesome:~]$ identify -format '%wx%h' W4.JPG | cut -d'x' -f1
1680
[john@awesome:~]$ identify -format '%wx%h' W4.JPG | cut -d'x' -f2
1050
1

Этот сценарий предполагает, что существует значительный разрыв в размерах между группами самых маленьких и самых больших файлов. В частности, самый маленький из больших файлов по крайней мере вдвое больше самого большого из маленьких файлов.

Назовите скрипт "imagedirstats" и запустите его в цикле, таком как этот:

find /path/to/main/branch -type d | while read subdir; do (cd "$subdir" && ~/bin/imagedirstats ); done

для поиска и удаления файлов в отдельных каталогах в дереве каталогов.

Вот сценарий:

#!/bin/bash
# from http://superuser.com/questions/135951/batch-deletion-of-smaller-files-from-group-of-files-via-unix-command-line
# by Dennis Williamson - 2010-04-29

prevn=1     # prevent division by zero
factor=4    # how close to the largest of the small files to set the threshold, 4 == one fourth of the way above
min=1000    # ignore files below this size

while read n
do
    (( ratio = n / prevn ))
    if (( ratio > 1 && n > min ))
    then
        break
    fi
    if (( n > 0 ))
    then
        prevn=$n
    fi
done < <(find . -maxdepth 1 -name "*.jpg" -printf "%s\n" | sort -n)
# for OS X, comment out the preceding line and uncomment this one:
# done < <(find . -maxdepth 1 -name "*.jpg" | stat -f "%z" | sort -n)

# the following line would be the GNU equivalent using stat(1) instead of printf
# it's included here for reference:
# done < <(find . -maxdepth 1 -name "*.jpg" | stat -c "%s" | sort -n)

(( size = (n - prevn) / factor + prevn ))

echo "Smallest of the large: $n"
echo "Largest of the small: $prevn"
echo "Ratio: $ratio"
echo "Threshold: $size"

if (( ratio < 2 ))
then
    read -p "Warning: ratio too small. Delete anyway? Only 'Yes' will proceed" reply
    if [[ $reply != "Yes" ]]
    then
        echo "Cancelled" >&2
        exit 1
    fi
fi

# uncomment the delete on the following line to actually do the deletion

find . -maxdepth 1 -name "*.jpg" -size -${size}c # -delete

Редактировать: перемещено предупреждение, так что полезная информация будет отображаться первой. Исправлен отсутствующий fi .

Редактировать 2: Сделано две команды find соответствии. Добавлен закомментированный вариант для OS X. Добавлена информация о запуске скрипта.

0

Если вы хотите сделать это на основе имени файла, попробуйте следующее:

find -name '*.jpg' | sed -ne 's:^\(.*\)\.jpg:\1s.jpg$:p' | xargs rm

Он найдет каждый файл .jpg, поставит "s" в конце имени файла (непосредственно перед «.») И удалит его.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .