I'm trying to copy massive pictures on a messy old hard drive that I can't open on Windows File Explorer (don't ask...) and I have to for the seek of helping my dear Grandma. I can do, navigate in it with Babun (awesome Windows shell).

So far I've tried commands:

$ find /cygdrive/h/Documents\ and\ Settings -name '*.jpeg|png|JPEG' -exec cp '{}' /cygdrive/f/tof \;

$ find /cygdrive/h/Documents\ and\ Settings -name '*.(jpeg|png|JPEG)' -exec cp '{}' /cygdrive/f/tof \;

No results... Is there something I'm missing?

  • 1
    find's -name predicate takes a glob, not a regular expression. try -regex (or -iregex for case-insensitive) or use parenthesis to OR multiple -name predicates, e.g. find ... \( -iname '*.jp*g' -o -iname '*.png' \) ...
    – cas
    Feb 7, 2018 at 0:48

2 Answers 2


find's -name predicate takes a glob, not a regular expression.

If you want to use regular expressions with find, use -regex (or -iregex for case-insensitive). For example:

find ... -regextype egrep -iregex '.*\.(jpe?g|png)$' ...

Alternatively, use parenthesis to OR multiple -name or -iname predicates, e.g.:

find ... \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) ...

NOTE: The parentheses need to be backslash-escaped to prevent the shell from interpreting them as a request for a sub-shell, resulting in -bash: syntax error near unexpected token('`

  • Thanks I think i get a better approche now. But still cannot make it work. find /cygdrive/h/Documents\ and\ Settings -regextype egrep -iregex '*.(jpeg|png)$ -exec cp '{}' /cygdrive/f/tof \; gives me find: ‘/cygdrive/h/Documents and Settings/All Users/Menu Démarrer/Programmes/Bridge Base Inc’: File exists. but without any action done. Same for the -iname alternative
    – user274630
    Feb 7, 2018 at 1:27
  • *.(jpeg|png)$ does not match anything with find, as find matches on the whole path, not just a simple search (and a regex starting with a * isn't really a valid regex anyway - it will "work" with most regex engines, for various values of "work", but by accident rather than by design. * is a modifier - zero-or-more - applied to the previous atom, starting a regex with it has no previous atom to modify). .*\.(jpe?g|png)$ matches filenames ending in .jpg, .jpeg or .png.
    – cas
    Feb 7, 2018 at 1:40

I don't think find is the right tools for this, rsync would probably be better, but if your happy having all the files end up in one directory, find will do it, but you need to remove the single quotes around the {} in the command line as that means use a literal {} instead of the filename.

  • It's not the shell that expands {} - so the usual quoting rules don't apply AFAIK Feb 7, 2018 at 0:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.