Wildcard not working in cp command when using exec
Try:
find . -type d -regex './[a-z]*' -exec bash -c 'cp -v "$1"/* ..' Cp {} \;
Discussion
Consider:
find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;
When bash sees this line, it performs pathname expansion on {}/*
. Since there (typically) is no directory named {}
, the *
is left as a literal *
. This is not what you want. You need pathname expansion to occur after find
has substituted in for {}
. By putting the cp
command in quotes and passing it as an argument to bash -c
, we achieve that goal.
A sample form for bash -c
looks like:
bash -c 'code...' a b c
This tells bash to assign a
to $0
, b
to $1
, c
to $2
and then execute code...
. If an error occurs, the shell uses $0
as the name of the program being executed (in the error message). Above, we chose Cp
as a descriptive name. Also, as above, {}
is substituted for $1
and we use use $1
in the code...
. When used this way, {}
doesn't need to be quoted (but it doesn't hurt if you do); find
handles any escaping that is needed. Inside code...
, however, $1
should be in double-quotes to protect against word splitting and pathname expansion.