Search code examples
bashfind

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

./myfind.sh first second

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

#!/bin/bash
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)

    #!/bin/bash
    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" )
    done
    
    find . "${args[@]}"
    

    Then your invocation might look like:

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