How to construct a find statement using multiple bash script arguments

To find a file containing more than one case-insensitive search term, I’m doing:

find . -iname "*first*" -iname "*second*"

I’d like to turn this into a utility script, so that I can just type

./ first second

However, since brace expansion happens before variable expansion, I can’t do:

find . {-iname "*${*}*"}

Note that the number of arguments will be variable, so I can’t hard-code just two -iname flags.

I’ve been warned against using bash eval as a workaround. Is there a better approach I can take?

>Solution :

The typical solution to this problem is to build an argument list in an array and then expand the array in double quotes to preserve each argument.

(note: concatentation with -o is only required if you mean to match first OR second – if you want to match first AND second then remove the -o)

args=( "-iname" "$1" ) # set the first iname option
shift # discard the first argument
for arg ; do
  # for each remaining argument, concatenate additional -iname options with -o
  args+=( "-o" "-iname" "$arg" )

find . "${args[@]}"

Then your invocation might look like:

# single quote each search pattern to prevent any interpretation by the shell
./ '*first*' '*second*'

Leave a Reply