Estoy tratando de ejecutar un comando similar al siguiente en un script bash. Debe buscar a través de todas las subcarpetas $sourcedir
y copiar todos los archivos de cierto tipo al nivel raíz de $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Esto parece estar bastante cerca, excepto que {}
no se pasa en cuanto $2
a-exec sh -c ...
Me gustaría hacer esto lo más cerca posible de la "manera correcta", con tolerancia para caracteres especiales en nombres de archivo (específicamente caracteres de comillas simples).
Editar: veo gente sugiriendo usar xargs
o encadenar argumentos. Tenía la impresión de que esto solo está bien para un número limitado de argumentos. Si tengo, por ejemplo, miles de archivos .jpg que intento copiar de varios directorios de galería en un directorio de presentación de diapositivas gigante, ¿seguirán funcionando las soluciones que encadenan argumentos?
Edición 2: mi problema era que faltaba un _
antes de mi primera opción para sh en el -exec
comando. Para cualquiera que tenga curiosidad sobre cómo hacer que el comando find funcione, agregue _
y todo estará bien:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Sin embargo, he aceptado una respuesta a continuación porque cumple la misma tarea, pero es más eficiente y elegante.
xargs
por la que alguna vez se creó, para manejar automáticamente grandes cantidades de argumentos en comandos regulares que tenían límites. También a tener en cuenta, la mayoría de los límites máximos de argumentos, se han mejorado enormemente para las utilidades GNU estándar. También verá un beneficio de rendimiento, evitando todas esas bifurcaciones de proceso, que en miles de archivos es relevante.