这是这个。
到目前为止,我已经拼凑了以下find
命令,该命令旨在打印(并且经过正确测试-delete
)所有 200 x 200px 或更低的 JPG:
find . -iname "*.jpg" -type f -exec bash -c 'for i; do size=($(identify -format "%wx%h" "$i")); (( size[1] < 200 && size[2] < 200 )); done;' \; -print
但是,通过管道传输命令wc -l
表明它正在选择目标集中的每个图像。
将其分解为for
循环本身表明它循环遍历大于 200px 的图像:
for i in *.jpg; do size=($(identify -format "%wx%h" "$i")); (( size[1] < 200 || size[2] < 200 )); echo $size; done;
210x163
1920x1200
1920x1200
240x240
246x138
215x215
1920x1200
1920x1200
240x240
240x240
1920x1200
对我来说,这似乎表明identify
这可能是无法匹配低于指定尺寸的图像的罪魁祸首,但据我所知,匹配的语法是正确的。
谁知道这可能是什么原因造成的?
答案1
该find
命令源自这个答案。现在我发现那里有一个错误,你复制了它。
这是错误:片段(( size[1] < 200 && size[2] < 200 ))
应该是,(( size[0] < 200 && size[1] < 200 ))
因为 Bash 中的数组是从 索引的0
。请注意,您需要使用-format "%w %h"
链接答案中使用的空格分隔格式 ( ),否则该方法将不起作用。
此外,您还添加了几个错误:
- 您需要
arbitrary-name {}
在 之前\;
。(在链接的答案中remove-files
是名称 和 ,+
用来代替\;
)。 如果你选择使用
\;
而不是+
, 就没有意义了for i
。如果你选择+
, 就没有什么意义了,-print
因为-exec … {} +
总是返回 true。所以-exec … {} \;
,无循环,-print
有意义;或-exec … {} +
,使用循环,而-print
原本要做的事情应该移到循环内部。
正如您所展示的,循环for
本身在语法上似乎是有效的;但它存在主要错误。
它循环遍历大于 200px 的图像
在检查图像之前,它如何知道给定的图像是否更大?它需要循环遍历所有图像。您可以根据图像是否较小有条件地运行某些操作。您的操作echo $size
不是有条件运行的。
固定代码:
和
-exec … \;
find . -iname "*.jpg" -type f -exec bash -c ' size=($(identify -format "%w %h" "$1")) (( size[0] < 200 && size[1] < 200 )) ' arbitrary-name {} \; -print
和
-exec … +
find . -iname "*.jpg" -type f -exec bash -c ' for i; do size=($(identify -format "%w %h" "$i")) (( size[0] < 200 && size[1] < 200 )) && printf "%s\n" "$i" done ' arbitrary-name {} +
请注意,前一种变体每个文件生成一个 shell;后一种变体更经济。