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!
-
1I'm afraid you'll have to write a bash script that calls find with all the extensions. – Mr Lister May 26 '13 at 10:08
-
Would it be combined somehow with the 'file' command that knows the type of file it is? – Edward May 26 '13 at 10:31
-
For _videos_, see the corresponding Q&A here: [Ask Ubuntu: How can I find all video files on my system?](https://askubuntu.com/q/844711/327339). For anyone wanting to add a new answer for images, you could probably just add it there as well. – Gabriel Staples May 23 '23 at 18:27
6 Answers
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

- 3,782
- 4
- 16
- 33

- 4,048
- 2
- 21
- 29
-
2Is there a similar approach that can be taken for video? It seems that replacing "image" with "video" skips quicktime and Matroska formats... – Elder Geek Apr 28 '16 at 14:44
-
1@ElderGeek I would run file on some examples and see if there was a piece of text I could grep for. In the image section of the awk solution you could separate patterns with alternation for example /video|image|foo/ would return all files that had the word video, image, or foo in their description from file. – f3xy Jun 09 '16 at 21:13
-
Any ideas on how I can get rid of the : GIF image or : JPEG image and just be left off with the name of the file plus the path so I can pass it to another command as an output? – VaTo Jul 02 '16 at 00:00
-
-
1Note that the `\w+` part would exclude results like `foo.svg: SVG Scalable Vector Graphics image`. To find for example `.svg` files, change `\w+` to `.*` – Løiten May 04 '17 at 13:38
-
the problem with this approach is that is will execute file command on all files in current dir, not the best for performances – el-teedee Jan 08 '18 at 19:42
-
1For macOS mojave, `grep` has no `-P` option, and the output of the `file` command is very verbose. By the way, it will be better if you could explain your command. – DawnSong Oct 26 '18 at 02:55
-
Be aware of this command parse filename can be manipulate if filename itself matched `^.+: \w+ image`, e.g. `hello: fake image`. – 林果皞 Jan 30 '21 at 20:31
-
Can you explain how this works please? I don't understand what is happening in the command. `find . -name '*'` finds all files of any name in your current directory, but I'm lost after that. – Gabriel Staples May 23 '23 at 17:56
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 -
The first oneliner leverages the following commands, find, file, and awk. The second oneliner adds tar. Your best bet is to consult your local man pages for the behavior of your specific system.

- 737
- 11
- 15
-
2This is really the default answer if you want to pipe the output.. Thanks! – Paulo Fidalgo Mar 07 '16 at 16:49
-
-
1
-
before using this command to create tar make sure you have enough free space! (in this case on root partition) – naXa stands with Ukraine Apr 06 '19 at 09:36
-
-
You would add to the find command as the talk about here https://stackoverflow.com/questions/4210042/how-to-exclude-a-directory-in-find-command – f3xy Jul 08 '20 at 15:35
-
Be aware of this command not able deal with filename contains `:`, consider this 3 solutions: 1. `find . -type f -exec file --mime-type {} \+ | rev | awk -F: '{ st = index($0, ":"); if (substr($0, 1, st) ~/\/egami/) print substr($0, st+1) }' | rev` 2. `find . -type f -exec file --mime-type {} \+ | awk -F: -vOFS=: '{if ($NF ~/image\//) {$NF=""; print $0} }' | sed 's/:$//'`. – 林果皞 Jan 30 '21 at 23:46
-
cont. 3. `find . -type f -exec file --mime-type {} \+ | awk '{ n=split($0, Arr, ":"); for (i=0; i
– 林果皞 Jan 30 '21 at 23:49 -
-
Can you explain how this works? What is `file --mime-type {} \+`, for instance?--among other things? – Gabriel Staples May 23 '23 at 18:02
-
Also, can you please expand your answer to have a version which searches for images _and_ videos all at once?--any media content, really. – Gabriel Staples May 23 '23 at 18:15
-
This is all run under an invocation of ```find``` for each file that is found find executes ```file --mime-type``` with the filename. The \+ is actually part of the find command which instructs find to run the file command in batches instead of once per file. – f3xy May 30 '23 at 17:44
-
by expanding the if in the awk section from ```if ($2 ~/image\//)``` to ```if ($2 ~/(image|video)\//)``` you now will receive a list of images and videos. You can add other types of files based on their [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) type – f3xy May 30 '23 at 17:58
find . -type f -exec file {} \; | grep -o -P '^.+: \w+ image'
should even be better.

- 2,208
- 19
- 32
-
3
-
-
2
-
1@Selah This command specifies `-type f`, which would get files but not folders and execute the `file` command, so it could be a bit quicker than j.holetzeck's answer. – liginity Jan 21 '21 at 02:47
-
1This command has issue if filename matched `^.+: \w+ image`, e.g. `hello: fake image`. Consider this solution: `find . -type f -print0 | xargs -0 bash -c 'for arg do file -b --mime-type "$arg" | grep -q '^image/' && echo "$arg"; done' _` . Explanation: 1. `file -b` output only filetype to avoid filename match `^.+: \w+ image`. 2. `-print0 | xargs -0` able deal with newline in filename while my other comments not deal with that exotic case. 3. `for` loop with trailing `_` to covers `'` or `$var` in filename) 4. `--mime-type` avoid `.psd`("I"mage) and `.eps`(no "image") file type issues. – 林果皞 Jan 31 '21 at 01:12
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}'

- 135
- 1
- 2
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).

- 7,826
- 4
- 44
- 55
-
1According to my limited testing my updated invocation executes faster than what you have currently, but I welcome the comments. Your use of xargs reminded me that find does something equivalent. Also the mime-types option to find is a good addition. It does produce a different results from what I had previously, but the biggest plus is it excludes virtual machine images. For an accurate comparison with awk you will need to combine grep piped in to cut since that is doing both of those things. Still awk will provide you more versatility. Thank you. – f3xy Apr 29 '20 at 20:15
-
Should change `cut -d ':' -f 1` to `rev | cut -d ':' -f 2- | rev` to print full filename contains `:`. e.g. `hello : world.jpg` – 林果皞 Jan 30 '21 at 20:21
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.

- 11
- 2
-
3This utility appears to rely on name of the file ending in a file extension. This is no where near as robust as checking the output of the file command. From the link you provide there is an example of your find invocation (`find ~/Pictures \( -iname "*.jpg" -or -iname "*.jpeg" -or -iname "*.png" -or -iname "*.tif" -or -iname "*.bmp" -or -iname "*.gif" -or -iname"*.xpm" -or -iname "*.nef" -or -iname "*.cr2" -or -iname "*.arw" \) -size +20k`) – f3xy Nov 03 '17 at 17:12