A colleague wanted to find all the files that end up *.disp
or *.frag
. Easy enough, right? In the shell you can say *.{disp,frag}
.
$ ls *.{disp,frag} foo.disp foo.frag
Except that this doesn’t work with find:
$ find . -name '*.{disp,frag}'
Why not? Because braces aren’t globs, so they’re not supported by find(1).
What can you do instead?
Firstly, you can use the -regex
flag.
$ find . -regex '.*.(disp|frag)' ./foo.disp ./foo.frag
This is particularly awful because find defaults to the emacs style of regexes (which took me ages to remember the details of) and means you end up with leaning toothpick syndrome. And you’re matching the whole filename, not a subset, so you have to have the .*
on the front.
The second option is to use find’s expression language. Find THIS FILE or THAT FILE.
$ find . ( -name '*.disp' -or -name '*.frag' ) -print ./foo.disp ./foo.frag
This is a bit more readable, but you have to remember that the parentheses are quoted because the shell likes to munch on them. Overall, it does seem preferable to -regex
though.
Like all these things, you can take it too far.