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.