Reputation: 133
My apologies if this is already answered, but if it is I can't find the proper search terms.
I'm trying to dynamically define search terms (based on user defined settings) for the find command:
# reading user settings results in array of filename patterns to delete:
patterns=("*.url" "*.html")
for i in ${patterns[@]}; do
find . -iname $i -delete
done
If I echo
the command, the resulting string looks correct, e.g.
find . -iname "*.url" -delete
find . -iname "*.html" -delete
I know I'm missing something obvious but nothing I've tried works.
I'm using Bash 4.4.5 if that helps.
----------------EDIT-----------------
My thanks to Charles Duffy and l'L'l for the correct solution(s). I had a hard time wrapping my head around the quotes in the array strings vs the quoted variables and failed to quote both variables at the same time.
Lesson learned: always quote shell variables.
Upvotes: 1
Views: 2684
Reputation: 295687
The answer by l'L'l is a good one, but let's make it a little more efficient, by invoking find
only once with all your patterns passed in a single command line:
patterns=("*.url" "*.html")
find_pat=( )
for i in "${patterns[@]}"; do
find_pat+=( -o -name "$i" )
done
find . -iname '(' "${find_pat[@]:1}" ')' -delete
When run, this will invoke:
find . -iname '(' -name '*.url' -o -name '*.html' ')' -delete
...thus deleting all files which match either *.url
or *.html
in a single pass.
Note:
patterns
array), on array expansion (so we iterate over the globs themselves and not their results), and on expansion into the find
command (so we pass find
the literal pattern syntax, not the result of expanding that syntax).-o
to the find_pat
array, but then expanding from the second element (arrays being 0-indexed), thus skipping that initial -o
. The syntax used here is parameter expansion.Upvotes: 5
Reputation: 47274
You need to double-quote your variables:
for i in "${patterns[@]}"; do
find . -iname "$i" -delete
...
This will prevent globbing and word splitting.
You can always check your script at https://www.shellcheck.net/ for errors as well...
Upvotes: 3