GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué find -exec mv {} ./target/ + no funciona?

Encontré el mismo problema en Mac OSX , usando un ZSH shell:en este caso no hay -t opción para mv , así que tuve que encontrar otra solución. Sin embargo, el siguiente comando tuvo éxito:

find .* * -maxdepth 0 -not -path '.git' -not -path '.backup' -exec mv '{}' .backup \;

El secreto era citar las llaves . No es necesario que las llaves estén al final del exec comando.

Probé bajo Ubuntu 14.04 (con BASH y ZSH conchas), funciona igual.

Sin embargo, al usar el + signo, parece que tiene que estar al final del exec comando.


La página del manual (o el manual de GNU en línea) explica prácticamente todo.

buscar comando -exec {} \;

Por cada resultado, command {} es ejecutado. Todas las apariciones de {} se reemplazan por el nombre del archivo. ; tiene el prefijo de una barra inclinada para evitar que el shell lo interprete.

buscar comando -exec {} +

Cada resultado se adjunta a command y ejecutado después. Teniendo en cuenta las limitaciones de longitud del comando, supongo que este comando puede ejecutarse más veces, con la página del manual apoyándome:

el número total de invocaciones del comando será mucho menor que el número de archivos coincidentes.

Tenga en cuenta esta cita de la página del manual:

La línea de comando se construye de la misma manera que xargs construye sus líneas de comando

Por eso no se permiten caracteres entre {} y + a excepción de los espacios en blanco. + hace que find detecte que los argumentos deben agregarse al comando como xargs .

La solución

Afortunadamente, la implementación GNU de mv puede aceptar el directorio de destino como argumento, ya sea con -t o el parámetro más largo --target . Su uso será:

mv -t target file1 file2 ...

Tu find el comando se convierte en:

find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+

Desde la página del manual:

-comando exec;

Ejecutar comando; verdadero si se devuelve el estado 0. Todos los siguientes argumentos para encontrar se toman como argumentos para el comando hasta que un argumento consiste en ';' se encuentra La cadena `{}' es reemplazada por el nombre del archivo actual que se está procesando en todos los lugares donde aparece en los argumentos del comando, no solo en los argumentos donde está solo, como en algunas versiones de find. Es posible que sea necesario escapar de ambas construcciones (con un `\') o citarlas para protegerlas de la expansión del shell. Consulte la sección EJEMPLOS para ver ejemplos del uso de la opción -exec. El comando especificado se ejecuta una vez para cada archivo coincidente. El comando se ejecuta en el directorio de inicio. Hay problemas de seguridad inevitables relacionados con el uso de la acción -exec; debería usar la opción -execdir en su lugar.

-comando ejecutivo {} +

Esta variante de la acción -exec ejecuta el comando especificado en los archivos seleccionados, pero la línea de comando se crea agregando cada nombre de archivo seleccionado al final; el número total de invocaciones del comando será mucho menor que el número de archivos coincidentes. La línea de comandos se construye de la misma manera que xargs construye sus líneas de comandos. Solo se permite una instancia de `{}' dentro del comando. El comando se ejecuta en el directorio de inicio.


El equivalente estándar de find -iname ... -exec mv -t dest {} + para find implementaciones que no admiten -iname o mv implementaciones que no admiten -t es usar un shell para reordenar los argumentos:

find . -name '*.[cC][pP][pP]' -type f -exec sh -c '
  exec mv "[email protected]" /dest/dir/' sh {} +

Usando -name '*.[cC][pP][pP]' , también evitamos depender de la configuración regional actual para decidir cuál es la versión en mayúsculas de c o p .

Tenga en cuenta que + , contrario a ; no es especial en ningún shell, por lo que no es necesario citarlo (aunque las comillas no dañarán, excepto, por supuesto, con shells como rc que no son compatibles con \ como operador de comillas).

El / final en /dest/dir/ es que mv falla con un error en lugar de renombrar foo.cpp a /dest/dir en el caso de que solo uno cpp archivo fue encontrado y /dest/dir no existía o no era un directorio (o enlace simbólico al directorio).


Linux
  1. Linux:¿Diferencia entre /dev/console, /dev/tty y /dev/tty0?

  2. ¿Por qué /bin/sh apunta a /bin/dash y no a /bin/bash?

  3. Instalar binarios en /bin, /sbin, /usr/bin y /usr/sbin, interacciones con --prefix y DESTDIR

  4. ¿Cuándo debo usar /dev/shm/ y cuándo debo usar /tmp/?

  5. /sys/ documentación?

Linux:¿/sbin/init no existe?

unix:///var/run/supervisor.sock no hay tal archivo

¿Por qué esta expresión regular no funciona en Linux?

¿Por qué poner otras cosas que no sean /home en una partición separada?

hacer eco o imprimir /dev/stdin /dev/stdout /dev/stderr

¿Por qué los directorios /home, /usr, /var, etc. tienen todos el mismo número de inodo (2)?