prueba algo como esto:
find /home/mine -iname "*.png" -printf "%P\n " | xargs -I % -n1 cp % /home/mine/pngcoppies/copy%
Para ver lo que sucede cuando ejecuta la búsqueda, simplemente escriba set -xv
-x:Imprime los comandos y sus argumentos a medida que se ejecutan.
-v :Imprime las líneas de entrada del shell a medida que se leen.
Esto es lo que tengo:
find . -name "*.xml" -exec echo {} \;
Da la salida:
./log.xml
./svnLog.xml
Y cuando intento:
set -xv
find . -name "*.xml" -exec echo {} \;
obtengo:
find . -name "*.xml" -exec echo {} \;
+ find . -name '*.xml' -exec echo '{}' ';'
./log.xml
./svnLog.xml
Y luego busque ejecutar echo pasando el nombre de archivo encontrado en lugar del literal:'{}'
pero cuando agregas algo al {}
como a continuación:
find . -name "*.xml" -exec echo something{} \;
+ find . -name '*.xml' -exec echo 'something{}' ';'
something{}
something{}
Aqui el echo se ejecuta dos veces por los 2 archivos xml que tengo y ya no hay mas '{}'
es la lista de parámetros del exec, no se va a reemplazar. así que obtuvimos el echo 'something{}'
por cada archivo encontrado.
Para lidiar con esto, puede pensar en ejecutar echo pasándole el nombre del archivo como parámetro como por ejemplo:
sh -xvc 'echo sothing/$0' filename
Ya sabemos qué es -x
y -v
. -c
es obtener el comando de la cadena posterior (man sh
)
entonces el resultado es:
sh -xvc 'echo somthing/$0' filename
+ sh -xvc 'echo somthing/$0' filename
echo somthing/$0
+ echo somthing/filename
sothing/filename
Usé 'echo somthing/$0
' entre ' ' para que $0 no se expanda por el shell actual. pruébalo con " " y verás la expansión de $0;)
Entonces, para volver a su 'problema', la búsqueda debe tener el siguiente formato:
find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \;
Y obtendremos:
find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \;
+ find . -name '*.xml' -exec sh -xvc 'echo sothing/$0' '{}' ';'
echo sothing/$0
+ echo sothing/./log.xml
sothing/./log.xml
echo sothing/$0
+ echo sothing/./svnLog.xml
sothing/./svnLog.xml
Como podemos ver, el find va a ejecutar el comando de shell echo sothing/$0
pasándole '{}'
(reemplazado por el nombre de archivo encontrado por find) por lo que obtenemos el echo sothing/./log.xml
deseado
set +xv
para eliminar el modo detallado y podemos obtener:
find . -name "*.xml" -exec sh -c 'echo "cp $0 someWhereElse/$0"' {} \;
cp ./log.xml someWhereElse/./log.xml
cp ./svnLog.xml someWhereElse/./svnLog.xml
entonces, en su caso, solo tiene que ejecutar la copia en un subshell (agregue sh
o bash
o prefiere shell después del exec) y deje find
pasa el nombre del archivo como parámetro al it;)
find /home/mine -iname "*.png" -exec sh -c 'cp $0 /home/mine/pngcoppies/copy/$0' {} \;
Espero que esto pueda ayudar y disculpe mi inglés.
De man find:"El -execdir primario es idéntico al -exec primario con la excepción de que la utilidad se ejecutará desde el directorio que contiene el archivo actual. El nombre de archivo sustituido por la cadena ``{}'' no está calificado".
find /home/mine -iname "*.png" -execdir cp {} /home/mine/pngcoppies/copy{} \;