我有一个带有子目录的目录。目录中有很多从网上爬来的图片。
我如何循环遍历每个文件并显示那些不是有效图像文件的文件?
它不应该基于文件扩展名。
我想出了这个脚本:
find . -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' | while read FILE; do
if ! identify "$FILE" &> /dev/null; then
echo "$FILE"
fi
done
但这不起作用,因为它也输出有效的图像。
答案1
find . -type f \
\( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \
-exec sh -c '! file -b --mime-type "$1" | grep -q "^image/"' sh {} \; \
-print
我的方法是使用-exec
自定义测试来测试文件。需要一个 shell 来构建管道。每个具有正确扩展名的文件都会运行一个单独的 shell,因此该解决方案的性能相当差。
shell 运行file -b --mime-type
,然后grep
检查结果是否以image/
.!
开头,如果管道开头则否定其退出状态,因此-exec
如果文件不是真正的图像,则整个测试成功。然后打印路径。
笔记:
- 省略
-name
测试来检查所有文件。 - 或者您可能想使用
-iname
而不是-name
。 -iname
但 POSIX 并不要求 。 也不是-b
的--mime-type
选项file
。以下产生略有不同的输出并且速度更快:
find . -type f \ \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \ -exec file --mime-type {} + \ | grep -v "\bimage/"
但一些文件名(例如带有换行符)或路径(带有
image/
)会破坏逻辑。
答案2
答案3
检查文件扩展名和魔法字节很容易被欺骗。请参阅https://unix.stackexchange.com/questions/189364/script-to-determine-if-apparent-image-files-are-real-image-files/189367#189367为了获得灵感,基本上使用 imagemagick 来检查图像是否有效,但即使这样也可能被欺骗!所以没有完美的检查方法。