I have a directory with sub-directories. In the directories, there are a lot of images, crawled from the web.
How do I loop through every file and show those files which are not valid image files?
It should not be based on file extension.
I came up with this script:
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
But this is not working, because it outputs valide images, too.
Best Answer
My approach uses
-exec
to perform a custom test on files. A shell is needed to construct a pipe. A separate shell is run for every file with the right extension, therefore the solution performs rather poorly.The shell runs
file -b --mime-type
, thengrep
checks if the result begins withimage/
.!
at the beginning of the pipe negates its exit status, so the entire-exec
test succeeds iff the file is not really an image. The path is then printed.Notes:
-name
tests to check all files.-iname
instead of-name
.-iname
is not required by POSIX though. Neither is-b
nor--mime-type
option offile
.The following yields a slightly different output and it's faster:
but some filenames (e.g. with newlines) or paths (with
image/
) will break the logic.