我想知道是否有一种方法可以使用命令行工具(Fedora 19)从目录中递归删除分辨率低于我想要的图像?
例如,我想保留水平至少 3000px、垂直至少 2000px 的图像,并删除任何其他图像。
答案1
这是一个可能的纯粹解决方案,取决于用于告知图像分辨率的bash
命令:identify
ImageMagick
( find . -type f | xargs identify ) | while read i
do
fn1=${i%%[*}
fn=${i%% *}
tail=${i#* * }
size=${tail%% *}
xsize=${size%%x*}
ysize=${size##*x}
if [[ ( $xsize -le 3000 ) || ( $ysize -le 2000 ) ]]
then
rm "$fn"
fi
done
不过,我建议先进行备份,然后使用更强大的工具来解析(并仔细检查)输出,identify
然后再自动删除文件,例如perl
。
答案2
扩展@The Vee 的答案,这里有一个一行程序,可以找到您想要的所有文件,前提是您安装了 ImageMagick、awk、sed、grep、cut、xargs 和 find:
( find . -type f | xargs identify ) | grep -E '^[.][^ ]+? [^ ]+? [0-9]+?x[0-9]+? ' | sed -re 's/^([.][^ ]+?) [^ ]+? ([0-9]+?)x([0-9]+?) .*$/\2 \3 \1/g' | while read resolution; do resx=$(echo "$resolution" | awk '{ print $1 }'); resy=$(echo "$resolution" | awk '{ print $2 }'); if [[ ( $resx -lt 3000 ) || ( $resy -lt 2000 ) ]]; then echo "$(echo "$resolution" | cut -d ' ' -f3-)"; fi; done
解释:
(
# Recursively print filenames in the current directory
find . -type f | \
# Pipe them into xargs which runs "identify" for each file
xargs identify
) | \
# Only keep the files that have been identified
grep -E '^[.][^ ]+? [^ ]+? [0-9]+?x[0-9]+? ' | \
# Extract filename, width and height using RegEx into the format "<width> <height> <filename>". The filename is at the end to account for spaces in the filename which will be handled by using `cut`
sed -re 's/^([.][^ ]+?) [^ ]+? ([0-9]+?)x([0-9]+?) .*$/\2 \3 \1/g' | \
# For each of these lines extracted, do the following
while read resolution; do
# Extract the width (first number)
resx=$(echo "$resolution" | awk '{ print $1 }')
# Extract the height (second number)
resy=$(echo "$resolution" | awk '{ print $2 }')
# Do the resolution check (use lower than, instead of lower equals)
if [[ ( $resx -lt 3000 ) || ( $resy -lt 2000 ) ]]; then
# Print the filename
echo "$(echo "$resolution" | cut -d ' ' -f3-)"
fi
done
上面的代码只打印文件名,因此如果您想删除它们,只需将其输入到管道中即可xargs
:
( find . -type f | xargs identify ) | grep -E '^[.][^ ]+? [^ ]+? [0-9]+?x[0-9]+? ' | sed -re 's/^([.][^ ]+?) [^ ]+? ([0-9]+?)x([0-9]+?) .*$/\2 \3 \1/g' | while read resolution; do resx=$(echo "$resolution" | awk '{ print $1 }'); resy=$(echo "$resolution" | awk '{ print $2 }'); if [[ ( $resx -lt 3000 ) || ( $resy -lt 2000 ) ]]; then echo "$(echo "$resolution" | cut -d ' ' -f3-)"; fi; done | xargs rm
如果您想要询问每个文件是否要删除它,请使用:
( find . -type f | xargs identify ) | grep -E '^[.][^ ]+? [^ ]+? [0-9]+?x[0-9]+? ' | sed -re 's/^([.][^ ]+?) [^ ]+? ([0-9]+?)x([0-9]+?) .*$/\2 \3 \1/g' | while read resolution; do resx=$(echo "$resolution" | awk '{ print $1 }'); resy=$(echo "$resolution" | awk '{ print $2 }'); if [[ ( $resx -lt 3000 ) || ( $resy -lt 2000 ) ]]; then echo "$(echo "$resolution" | cut -d ' ' -f3-)"; fi; done | xargs rm --interactive=always
添加-v
还将rm
打印被删除的文件。
如果您不想像上面描述的那样通过管道传输,您也可以删除内联:
( find . -type f | xargs identify ) | grep -E '^[.][^ ]+? [^ ]+? [0-9]+?x[0-9]+? ' | sed -re 's/^([.][^ ]+?) [^ ]+? ([0-9]+?)x([0-9]+?) .*$/\2 \3 \1/g' | while read resolution; do resx=$(echo "$resolution" | awk '{ print $1 }'); resy=$(echo "$resolution" | awk '{ print $2 }'); if [[ ( $resx -lt 3000 ) || ( $resy -lt 2000 ) ]]; then filetodelete=$(echo "$resolution" | cut -d ' ' -f3-); echo "$filetodelete $resx $resy"; rm -v "$filetodelete"; fi; done
确保您有备份!不要相信上述命令在所有情况下都能 100% 发挥作用。