La mejor manera de ejecutar un comando en cada archivo en un árbol de directorios

13

Parece que hay varias formas de hacerlo, incluidos los bucles en el script de shell, find y xargs. ¿Cuál de estos es el mejor y cuál es el más portátil?

Brian Lyttle
fuente

Respuestas:

13
find . -exec <command> {} \;

para el directorio actual como raíz del árbol o en general:

find <directory> -exec <command> {} \;
txwikinger
fuente
44
en algunos sistemas, find no tiene la opción -exec allí, puede usar find. El | xargs <Command>
Hemant
44
De hecho, y si necesita filtrar por algo, intente -name "*.c"o por ejemplo -type dpara directorios ...
Find puede hacer cosas sorprendentemente complejas: puede consultar la página de manual , unixhelp.ed.ac.uk/CGI/man-cgi?find , para ver la lista completa de opciones.
Lucas Jones
También es posible que desee tener cuidado con los nombres de archivos con espacios, que pueden romper el enfoque -exec y xargs. Ver tinyurl.com/ygvgmw5
Shawn Chin
Si es posible, use el find ... | xargs ...idioma, procesa los archivos en lotes, y esto generalmente será más rápido (menos procesos iniciados).
vonbrand
5

Use la -print0opción para buscar y la -0opción xargssi tiene nombres de archivo o directorio con espacios:

find {dir} -print0 | xargs -0r {command}

La -print0opción para buscar imprime los nombres de archivo como una NULlista separada por espacios en blanco en lugar de espacios en blanco, mientras que la -0opción para xargsindicar que rompa su entrada en NULlugar de espacios en blanco. Dado que NULes uno de los caracteres que no está permitido en los nombres de archivo Unix, no hay forma de que se confunda con parte de un nombre de archivo.

La -ropción está ahí para que xargsno le dé un error si no tiene entrada.

dhd
fuente
3

Si la portabilidad es un problema, me mantendría alejado de las formas específicas de hacerlo (hay muchas personas que usan muchos shells diferentes, pero en general find y xargs son herramientas realmente básicas que nadie se atrevería a cambiar de manera radical) .

El uso de argumentos básicos de find y xargs debería proporcionarle una solución más portátil.

nc3b
fuente
2

Si la agrupación de argumentos es aceptable, busque | xargs probablemente dará un mejor rendimiento, ya que ejecutará el comando muchas menos veces que find -exec. Si desea ejecutar el comando cada vez para cada archivo o ejecutar en el subdirectorio del archivo, probablemente debería usar find -exec o -execdir.

Como regla general, es preferible mantenerse alejado de los bucles específicos de shell; find & xargs son suficientes para la mayoría de los escenarios.

Eugen Anghel
fuente
1

Asegúrese de que la versión del comando que está utilizando no tenga una marca para la operación recursiva. :)


fuente
0
find [args] -print | xargs {command}

Funciona mejor para mi.

Josh K
fuente
2
-1 No funcionará para nombres de archivo que contengan espacios. Mejor uso find -print0 | xargs -0.
starblue