我有大量(超过 400 个)目录,里面都是照片。我想要做的是保留这些照片的较大尺寸。每个目录中有 31 到 66 个文件。
每个目录都有缩略图和更大的版本,以及一个名为example.jpg
我使用以下命令轻松发送了 example.jpg 文件:
rm */example.jpg
我最初以为删除缩略图很容易,但问题是它们的名称不一致。典型的模式是photo1.jpg
和photo1s.jpg
。我这样做了rm */photo*s.jpg
,但结果发现一些文件的名称photoXs.jpg
实际上更大而不是更小。啊。
因此,我想要做的是扫描每个目录的文件大小并删除(或移动)缩略图。我最初以为我只是扫描ls -R
每个文件并提取每个文件的大小,然后将它们保存在阈值以下。问题是什么?在一个目录中,大文件为 1.1 MB,缩略图为 200k。在另一个目录中,大文件为 200k,小文件为 30k。
更糟糕的是,这些文件实际上大多都有名称photo1.jpg
- 因此,如果不重命名,简单地将它们全部放在同一个文件夹中、按大小排序并分组删除是行不通的,如果可能的话,我宁愿将它们保留在各自的文件夹中。
我几乎决定只手动完成所有操作,但后来想在这里问一下。
您将如何完成这项任务?
答案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 添加了注释掉的变体。添加了有关运行脚本的信息。
答案2
如果您发现有一些特定的截止值,例如所有大图片都大于 200KB,那么您可以执行以下操作:
find */*.jpg -size -200k -delete
您可能需要先制作一个备份。
答案3
如果文件大小不一致,图像尺寸是否一致?
您可以使用identify
ImageMagick 附带的工具来获取图像尺寸。通过一些简单的 bash 脚本,您可以根据图像的大小对其进行处理。
要获取图像的宽度和高度,请使用identify
:
识别 -格式'%wx%h'文件名
您将获得如下输出:
[john@awesome:~]$ 识别 -格式'%wx%h' W4.JPG 1680x1050
然后您可以使用该cut
实用程序来获取脚本中的数字:
[john@awesome:~]$ 识别 -格式'%wx%h'W4.JPG | 剪切-d'x'-f1 1680 [john@awesome:~]$ 识别 -格式'%wx%h' W4.JPG | 剪切 -d'x' -f2 1050
答案4
如果您想根据文件名执行此操作,请尝试以下操作:
find -name '*.jpg' | sed -ne 's:^\(.*\)\.jpg:\1s.jpg$:p' | xargs rm
它将找到每个 .jpg 文件,在文件名末尾(“.”之前)添加一个“s”并将其删除。