208

I need to find all image files from directory (gif, png, jpg, jpeg).

find /path/to/ -name "*.jpg" > log

How to modify this string to find not only .jpg files?

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
Kirzilla
  • 16,368
  • 26
  • 84
  • 129

10 Answers10

221
find /path/to -regex ".*\.\(jpg\|gif\|png\|jpeg\)" > log
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 11
    Does not work for me on mac, but works with the -E (extended) option (maybe the pipe is an extended feature?): find -E /path/to -iregex ".*\.(jpg|gif|png|jpeg)" > log – ling Oct 21 '15 at 07:38
149
find /path/to/  \( -iname '*.gif' -o -iname '*.jpg' \) -print0

will work. There might be a more elegant way.

JoseK
  • 31,141
  • 14
  • 104
  • 131
  • 16
    -iname would be case insensitive – Chris Koston Nov 21 '12 at 17:24
  • 1
    @Gerald: It's likely you need to group your OR expression in escaped parentheses: `find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -exec ls -l {} \;` otherwise the exec only applies to the last part (`-iname '*.jpg' ` in this case). – Dennis Williamson Nov 08 '18 at 21:50
  • 1
    That's an important remark. `find /path/to/ -iname '*.gif' -o -iname '*.jpg' -print0` will only print the jpg files! You need brackets here: `find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -print0` – Anne van Rossum Feb 11 '20 at 16:35
35

find -E /path/to -regex ".*\.(jpg|gif|png|jpeg)" > log

The -E saves you from having to escape the parens and pipes in your regex.

tboyce12
  • 1,449
  • 14
  • 28
  • 3
    my find doesn't have this -E – wieczorek1990 Aug 18 '14 at 20:58
  • 1
    Hmmm the `-E` option tells `find` to use "extended regular expressions". Several other tools have a similar option, but I'm not sure this option is available on all UNIX distributions. – tboyce12 Aug 18 '14 at 23:12
  • 8
    Works on Mac OS, too. – c.gutierrez Aug 20 '14 at 03:32
  • 4
    @tboyce12 Working on ubuntu, I can specify the -regextype to simplify the regex expression: `find . -regextype posix-extended -regex ".*\.(jpg|gif|png|jpeg)"`. – doub1ejack Oct 23 '15 at 17:37
  • How do I edit that regex so that it is not case-sensitive (a.k.a. will match files that end in `.JPG` rather just `.jpg`)? – cjm Jan 10 '17 at 05:47
  • 1
    @cjm Maybe `find -E /path/to -iregex ".*\.(jpg|gif|png|jpeg)" > log`. Using the `-iregex` flag tells `find` to match case insensitively. – tboyce12 Jan 10 '17 at 23:58
12
find /path/to/ -type f -print0 | xargs -0 file | grep -i image

This uses the file command to try to recognize the type of file, regardless of filename (or extension).

If /path/to or a filename contains the string image, then the above may return bogus hits. In that case, I'd suggest

cd /path/to
find . -type f -print0 | xargs -0 file --mime-type | grep -i image/
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
10
find /path -type f \( -iname "*.jpg" -o -name "*.jpeg" -o -iname "*gif" \)
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • 2
    Could you explain why you added the (escaped) parentheses around the name/iname parameters? –  Apr 12 '17 at 14:16
  • Any reason for the inconsistency? `-iname *.jpg`, `-o -name *.jpeg`, `-o -iname *gif` all have a slightly different format. – Abandoned Cart Apr 26 '18 at 06:15
  • if you could at least explain differencies with other answers. – el-teedee May 01 '19 at 21:50
  • `-o` - logical OR. Not an inconsistency, just joins together the `-iname` clauses. `-iname "*gif"` would match a filename ending `foogif`, whereas `-iname "*.gif"` would not. – asinoladro Jul 25 '22 at 17:57
8

On Mac OS use

find -E packages  -regex ".*\.(jpg|gif|png|jpeg)"
jww
  • 97,681
  • 90
  • 411
  • 885
7ynk3r
  • 958
  • 13
  • 17
6

In supplement to @Dennis Williamson 's response above, if you want the same regex to be case-insensitive to the file extensions, use -iregex :

find /path/to -iregex ".*\.\(jpg\|gif\|png\|jpeg\)" > log
TCW
  • 133
  • 1
  • 5
3
find -regex ".*\.\(jpg\|gif\|png\|jpeg\)"
Shrikant
  • 393
  • 6
  • 7
1

Adding -regextype posix-extended option only worked in my case:

sudo find . -regextype posix-extended -regex ".*\.(css|js|jpg|jpeg|png|ico|ttf|woff|svg)" -exec chmod 0640 {} \;
AamirR
  • 11,672
  • 4
  • 59
  • 73
0

in case files have no extension we can look for file mime type

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 ~ /audio|video|matroska|mpeg/) print $1 }'

where (audio|video|matroska|mpeg) are mime types regex

&if you want to delete them:

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 ~ /audio|video|matroska|mpeg/) print $1 }' | while read f ; do
  rm "$f"
done

or delete everything else but those extensions:

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 !~ /audio|video|matroska|mpeg/) print $1 }' | while read f ; do
  rm "$f"
done

notice the !~ instead of ~

k. Doe
  • 11