GNU/Linux >> Tutoriales Linux >  >> Linux

Usando tanto el nombre base como la ruta completa en find -exec

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{} \;

Linux
  1. Uso de sed para buscar y reemplazar archivos de texto en Linux

  2. ¿Usando 'sed' para buscar y reemplazar?

  3. Usando grep y sed para encontrar y reemplazar una cadena

  4. busque y elimine archivos con espacio usando el comando de búsqueda en Linux

  5. Enumere el archivo usando el comando ls en Linux con la ruta completa

Extraiga el nombre base del archivo sin ruta y extensión en bash

Encontrar archivos ejecutables usando ls y grep

¿Cómo usar / (separador de directorio) tanto en Linux como en Windows en Python?

Systemd:Uso de After y Requires

¿Cómo ejecuto múltiples comandos cuando uso find?

¿Cómo encontrar argumentos de proceso completo y puertos de escucha asociados?