¿Cómo integrar mv command after find command?

Estoy buscando files cuyo nombre contenga AAA dentro de su ruta usando el siguiente command:

 find path_A -name "*AAA*" 

Dado el resultado mostrado por el command anterior, quiero mover esos files a otra ruta, digamos path_B . En lugar de mover esos files uno por uno, ¿puedo optimizar el command moviendo esos files justo después del command find?

Related of "¿Cómo integrar mv command after find command?"

Con GNU mv :

 find path_A -name '*AAA*' -exec mv -t path_B {} + 

Eso usará la opción find -exec que reemplaza {} con cada resultado de búsqueda por turno y ejecuta el command que le das. Como se explicó en el man find :

  -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountenetworking. 

En este caso, estamos usando la versión + de -exec para que -exec menor cantidad posible de operaciones mv :

  -exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca‐ tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory. 

También puedes hacer algo como abajo.

 find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B 

Dónde,

  1. -0 Si hay espacios en blanco o caracteres (incluidas las líneas nuevas), muchos commands no funcionarán. Esta opción tiene cuidado de los nombres de files con espacio en blanco.
  2. -I Reemplace las ocurrencias de replace-str en los arguments iniciales con nombres leídos de la input estándar. Además, los espacios en blanco sin cita no terminan los elementos de input; en cambio, el separador es el carácter de nueva línea.

Pruebas

sourcedir dos directorys como sourcedir y destdir . Ahora, creé sourcedir files dentro de sourcedir como file1.bak , file2.bak y file3 with spaces.bak

Ahora, ejecuté el command como,

 find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/ 

Ahora, dentro del destdir , cuando hago ls , puedo ver que los files se han movido de sourcedir a destdir .

Referencias

http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/

El -exec es la mejor manera de hacer esto. Si, por alguna razón, esta no es una opción, también puede leer los resultados en un bucle:

 find path_A -name "*AAA*" -print0 | while IFS= read -r -d $'\0' file; do mv "$file" path_B; done 

Esa es la manera segura, puede tratar con nombres de files que contienen espacios, líneas nuevas u otros caracteres extraños. Una manera más simple, pero que falla a less que los nombres de sus files estén formados únicamente por caracteres alfanuméricos simples , es

 mv $(find path_A -name "*AAA*") path_B 

Pero usa el ciclo while.

Para beneficio de los usuarios de OS X que se encuentran con esta pregunta, la syntax en OS X es ligeramente diferente. Suponiendo que no desea search recursivamente en los subdirectorys de path_A :

 find path_A -maxdepth 1 -name "*AAA*" -exec mv {} path_B \; 

Si desea search todos los files recursivamente en path_A :

 find path_A -name "*AAA*" -exec mv {} path_B \; 

De otra manera

 for f in `find path_A -name "*AAA*"`; do mv $f /destination/dir/; done 

Usando solo las características POSIX de find (y también de mv ):

 find path_A -name '*AAA*' -exec sh -c 'mv "$@" path_B' find-sh {} + 

Otras lecturas:

  • ¿Por qué el bucle sobre la salida de resultados es una mala práctica?