El comodín no funciona en el comando cp cuando se usa exec

4

Quiero copiar todos los archivos en todos los directorios al directorio padre, pero recibo el error

./img/* is not a directory

Por ejemplo. Aquí está el comando que usé. ¿Hay una mejor manera de hacer esto?

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;
m0meni
fuente

Respuestas:

3

Tratar:

find . -type d -regex './[a-z]*' -exec bash -c 'cp -v "$1"/* ..' Cp {} \;

Discusión

Considerar:

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;

Cuando bash ve esta línea, realiza la expansión del nombre de ruta en {}/*. Como allí (normalmente) no hay un directorio con nombre {}, *se deja como literal *. Esto no es lo que quieres. Necesita que se produzca la expansión del nombre de ruta después de find haber sustituido {}. Al poner el cpcomando entre comillas y pasarlo como argumento bash -c, logramos ese objetivo.

Un formulario de muestra para bash -cparecerse a:

bash -c 'code...' a b c 

Esto le dice a bash que asigne aa $0, ba $1, ca $2y luego ejecute code.... Si se produce un error, el shell se usa $0como el nombre del programa que se está ejecutando (en el mensaje de error). Arriba, elegimos Cpcomo nombre descriptivo. Además, como arriba, {}se sustituye $1y usamos $1en el code.... Cuando se usa de esta manera, {}no necesita ser citado (pero no hace daño si lo hace); findmaneja cualquier escape que sea necesario. code...Sin embargo, el interior $1debe estar entre comillas dobles para proteger contra la división de palabras y la expansión del nombre de ruta.

John1024
fuente
¡Muchas gracias! ¿Podría explicar por qué funciona ahora?
m0meni
@ AR7 Acabo de actualizar la respuesta. Avísame si eso ayuda.
John1024
Ayuda mucho Me hiciste el día.
m0meni
1

Esto también podría funcionar

cd your_directory
cp -rp * /absolut_path_to_parent_directory
Ryder
fuente