Below are some examples of a find
command I'm trying to run. I'm looking for different ways that I might be able to use globbing to generate (as an example) a find command with predicates joined together.
Doesn't work because find
needs a -name before each one and a -o between each.
find . -name \*.{sh,pl,sql}
#find . -name *.sh *.pl *.sql
Doesn't work because of trailing -o
. Could pull a guaranteed to fail argument there, but not ideal. Also, my shortcut is now longer than my output.
find . `for X in {sh,pl,sql}; do echo -name \\\*.$X -o ;done`
#find . -name \*.sh -o -name \*.pl -o -name \*.sql -o
Fails because they're grouped as one argument (find: unknown predicate '-name *.sh'
). Also, still exhibiting a lack of joining with -o.
find . -name\ \*.{sh,pl,sql}
Works, but doesn't involve globbing (re: non-answer):
find . -regex '.*\(sh\|pl\|sql\)'
Best Answer
The
-false
idea is the key, IMHO. I'm just adding to it:You just quote everything to make bash repeat the whole pattern, including
-o -name
, and then "break" the grouping made by the quoting by returning it from a subshell. The problem with this approach is that quotes in the pattern won't work.EDIT: See Michał Šrajer's comment for another pitfall of this solution. Note that you can't just put a backslash before the star: the command substitution returns either a
*
, which will get expanded, or a\*
, which will get passed as-is to find (!). At least, that's how my local bash works.This is the best I can do:
Good luck :)
Btw, if you are not going to add more parameters to
find
, of course just usexargs
; in that case it works perfectly, with quotes and everything: