findpuede hacer coincidir patrones y ejecutar comandos. No es necesario canalizar su salida:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
jáquer
1
Sí, puede, sin embargo, a menudo es más fácil leer una tubería, también las capacidades de coincidencia de patrones grepsuperan con creces los patrones de shell simples utilizados en el -nameparámetro find. xargsTambién es mucho más poderoso que el -execparámetro find.
Mike Insch
2
La solución de @jaquer es mucho mejor porque en MacOSX la utilidad xargs no tiene la opción -i. Pero su solución funciona a las mil maravillas.
bialix
Estaba luchando con un mensaje de error en el argumento -i de xargs hasta que leí el comentario de @bialix sobre la solución de jaquer, que funcionó perfectamente en mi Mac. Gracias
svannoy
14
Si está utilizando Bash, puede activar la globstaropción de shell para que coincida con archivos y directorios de forma recursiva:
shopt -s globstar
cp src/**/*.so dst
Si necesita buscar archivos cuyos nombres comiencen con ., y / o archivos en y bajo directorios cuyos nombres comiencen con ., configure la dotglobopción también (por ejemplo, con shopt -s dotglob). Puede configurarlos en un solo comando:
+1. Sin embargo, esto supone que existen los directorios correspondientes a las rutas de origen relativas dst. En caso de que no sea así, úselo cp --parents. Además, asegúrese de citar los nombres de archivo. Por lo tanto: ... | xargs -i cp --parents "{}" dst(tenga en cuenta que el último argumento para cpahora es "solo" el directorio de destino). El comando se puede hacer aún más corto (y probablemente más rápido) utilizando la -tbandera: ... | xargs cp --parents -t dst.
Y esto debería reducir el número de cpprocesos: ... -exec cp -t dst/ {} +.
Kamil Maciorowski
¡Hola Kamil! ¡Gracias por el comentario! ¿Puede explicarme cómo su solución agiliza las cosas! Siempre dispuesto a aprender más :)
Kyriakos
Cuando termina -execcon ;, {}se reemplaza por un camino a la vez. Obtiene un separado cppara cada archivo. Con la +sintaxis findreemplaza {}con múltiples resultados (hasta un límite definido por el sistema de longitud de la línea de comando; restricción: {}debe ser lo último antes +, por lo tanto cp -t). Crear y finalizar un proceso es algo relativamente costoso. Por esta razón, es bueno usarlo +cuando esperes muchos resultados. En este caso, copiar muchos archivos puede tomar mucho tiempo de todos modos, por lo que la diferencia puede pasar desapercibida; Sin embargo, es una buena práctica.
Kamil Maciorowski
1
El grep puede reemplazarse usando find's -name :
find src/-type f -name "*.so"| xargs -i cp {} dst/{}
findpuede hacer coincidir patrones y ejecutar comandos. No es necesario canalizar su salida:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'grepsuperan con creces los patrones de shell simples utilizados en el-nameparámetrofind.xargsTambién es mucho más poderoso que el-execparámetrofind.Si está utilizando Bash, puede activar la
globstaropción de shell para que coincida con archivos y directorios de forma recursiva:Si necesita buscar archivos cuyos nombres comiencen con
., y / o archivos en y bajo directorios cuyos nombres comiencen con., configure ladotglobopción también (por ejemplo, conshopt -s dotglob). Puede configurarlos en un solo comando:fuente
Probé el comando sugerido por Mike:
pero terminó volcando todos los archivos en el directorio
dstcon sus rutas relativas perdidas.Para mantener las rutas relativas, el comando debe modificarse para esto:
fuente
dst. En caso de que no sea así, úselocp --parents. Además, asegúrese de citar los nombres de archivo. Por lo tanto:... | xargs -i cp --parents "{}" dst(tenga en cuenta que el último argumento paracpahora es "solo" el directorio de destino). El comando se puede hacer aún más corto (y probablemente más rápido) utilizando la-tbandera:... | xargs cp --parents -t dst.... | xargs cp {} --parents -t dst.Otra forma de hacer esto es así:
fuente
cpprocesos:... -exec cp -t dst/ {} +.-execcon;,{}se reemplaza por un camino a la vez. Obtiene un separadocppara cada archivo. Con la+sintaxisfindreemplaza{}con múltiples resultados (hasta un límite definido por el sistema de longitud de la línea de comando; restricción:{}debe ser lo último antes+, por lo tantocp -t). Crear y finalizar un proceso es algo relativamente costoso. Por esta razón, es bueno usarlo+cuando esperes muchos resultados. En este caso, copiar muchos archivos puede tomar mucho tiempo de todos modos, por lo que la diferencia puede pasar desapercibida; Sin embargo, es una buena práctica.El grep puede reemplazarse usando find's -name :
fuente