tags:

views:

888

answers:

3

I was trying to get a list of all python and html files in a directory with the command find Documents -name "*.{py,html}".

Then along came the man page:

Braces within the pattern (‘{}’) are not considered to be special (that is, find . -name 'foo{1,2}' matches a file named foo{1,2}, not the files foo1 and foo2.

As this is part of a pipe-chain, I'd like to be able to specify which extensions it matches at runtime (no hardcoding). If find just can't do it, a perl one-liner (or similar) would be fine.

Edit: The answer I eventually came up with include all sorts of crap, and is a bit long as well, so I posted it as an answer to the original itch I was trying to scratch. Feel free to hack that up if you have better solutions.

+7  A: 

Use -o, which means "or":

find Documents -name "*.py" -o -name "*.html"

Edit: Sorry, just re-read the question... you'd need to build that command line programmatically, which isn't that easy.

Are you using bash (or Cygwin on Windows)? If you are, you should be able to do this:

ls **/*.py **/*.html

which might be easier to build programmatically.

RichieHindle
I'm using zsh, which, as a general rule, supports all bashisms, plus more.
Xiong Chiamiov
Zsh supports `**` for recursive search; Bash only supports it in versions 4.0 and up, and only with `shopt -s globstar`.
ephemient
+3  A: 

You could programmatically add more -name clauses, separated by -or:

find Documents -name "*.py" -or -name "*.html"

Or, go for a simple loop instead:

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done
Stephan202
A: 

I had a similar need. This worked for me:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print
bkidd