List all graphic image files with find?
LinuxGraphicsFindLinux Problem Overview
There are many types of graphic images in this huge archive such as .jpg, .gif, .png, etc. I don't know all the types. Is there a way with 'find' to be able to have it list all the graphic images regardless of their dot extension name? Thanks!
Linux Solutions
Solution 1 - Linux
This should do the trick
find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image'
example output:
./navigation/doc/Sphärische_Trigonometrie-Dateien/bfc9bd9372f650fd158992cf5948debe.png: PNG image
./navigation/doc/Sphärische_Trigonometrie-Dateien/6564ce3c5b95ded313b84fa918b32776.png: PNG image
./navigation/doc/subr_1.jpe: JPEG image
./navigation/doc/Astroanalytisch-Dateien/Gamma.gif: GIF image
./navigation/doc/Astroanalytisch-Dateien/deltaS.jpg: JPEG image
./navigation/doc/Astroanalytisch-Dateien/GammaBau.jpg: JPEG image
Solution 2 - Linux
The following suits me better since in my case I wanted to pipe this list of files to another program.
find . -type f -exec file --mime-type {} \+ | awk -F: '{if ($2 ~/image\//) print $1}'
If you wanted to tar the images up (as someone in the comments) asked
find . -type f -exec file --mime-type {} \+ | awk -F: '{if ($2 ~/image\//) printf("%s%c", $1, 0)}' | tar -cvf /tmp/file.tar --null -T -
Solution 3 - Linux
find . -type f -exec file {} \; | grep -o -P '^.+: \w+ image'
should even be better.
Solution 4 - Linux
Grepping or using awk for "image" only will not do it. PSD-files will be identified by "Image" with a capital "I" so we need to improve the regexp to either be case insensitive or also include the capital I. EPS-files will not contain the word "image" at all so we need to also match for "EPS" or "Postscript" depending on what you want. So here is my improved version:
find . -type f -exec file {} \; | awk -F: '{ if ($2 ~/[Ii]mage|EPS/) print $1}'
Solution 5 - Linux
Update (2022-03-03)
This is a refined version with the following changes:
- Remove
xargs
. - Support filenames which contains
:
based on 林果皞's comment.
find . -type f |
file --mime-type -f - |
grep -F image/ |
rev | cut -d : -f 2- | rev
Below is a more performant solution compared to the chosen answer:
find . -type f -print0 |
xargs -0 file --mime-type |
grep -F 'image/' |
cut -d ':' -f 1
- Use
-type f
instead of-name '*'
since the former will search only files while the latter search both files and directories. xargs
executefile
with arguments as many as possible, which is super fast compared tofind -exec file {} \;
which executesfile
for each found.grep -F
is faster since we only want to match fixed string.cut
is faster thanawk
(more than 5 times faster as I can recall).
Solution 6 - Linux
Related to the same problem, I just published a tool called photofind (https://github.com/trimap/photofind). It behaves like the normal find-command but is specialized for image files and supports filtering of results also based on the EXIF-information stored within the image files. See the linked github-repo for more details.