7

I would like to define an expression for find which includes a wildcard in a -name subexpression:

find_expression="-type f -name *.csv -mtime +14"

And then use it in a couple of places later on:

find /var/data $find_expression -delete -print

If i don't quote the use of $find_expression, then when the variable is expanded, the glob is resolved, and if there happens to be a CSV file in the current directory, that find command is going to do the wrong thing.

If i do quote the use of $find_expression, then when the variable expanded, it is not split into multiple arguments to find, and the find command does the wrong thing.

This doesn't help:

find_expression="-type f -name '*.csv' -mtime +14"

I believe because it results in a fourth argument which actually starts and ends with single quote characters.

I could surround the invocation of find with a set -f / set +f pair. However, that means i couldn't then use a glob for the paths given to the find expression, so it's not a general solution.

Perhaps i could use an array here.

But is there any way to specifically expand a string into arguments without resolving globs?

Tom Anderson
  • 936
  • 2
  • 7
  • 20
  • 1
    See [Correct way of building variable length argument line to external command in bash](https://unix.stackexchange.com/questions/444113/correct-way-of-building-variable-length-argument-line-to-external-command-in-bas) and [Storing `find` parameters in a variable](https://unix.stackexchange.com/questions/6547/storing-find-parameters-in-a-variable) – steeldriver Mar 08 '21 at 19:20
  • Since it's Bash, use an array. – ilkkachu Mar 08 '21 at 19:23

1 Answers1

5

Use an array and quote it:

expression=('-type' 'f' '-name' '*.csv' '-mtime' '+14')
find /var/data "${expression[@]}" -delete -print

Each element will expand separately but without performing word splitting/globbing.

jesse_b
  • 35,934
  • 12
  • 91
  • 140