2009-08-24 4 views
7

Tengo un gran conjunto de directorios para los que estoy tratando de calcular el tamaño total de cientos de archivos .txt. Intenté esto, que trabaja sobre todo:¿Por qué "buscar. -name * .txt | xargs du -hc" da múltiples totales?

find . -name *.txt | xargs du -hc 

Pero en vez de darme un total al final, consigo varios. Mi suposición es que la tubería solo transmitirá tantas líneas de resultados de búsqueda a la vez, y du solo funciona en cada lote como viene. ¿Hay alguna forma de evitar esto?

Gracias! Alex

+0

Hm, ok. Intenté: encontrar. -name * .txt | xargs -n 100000 du -hc Pero eso no parece funcionar; obtengo más subtotales, no menos. Probando encontrar. -name * .txt | xargs -L 1000 du -hc doesnt 'parece funcionar bien tampoco. O "xargs: lista de argumentos demasiado larga" o solo funciona en unos pocos archivos. ¿Alguna otra idea? ¡Gracias! Alex –

Respuesta

11

Cómo sobre el uso del --files0-de opción de du? Habría que generar la salida de archivos terminada en nulo apropiada:

find . -name "*txt" -exec echo -n -e {}"\0" \; | du -hc --files0-from=- 

funciona correctamente en mi sistema.

+0

¡Funciona muy bien para mí! –

+2

ah, esto funcionó para mí, pero utilicé find -print0 en lugar de las cosas del eco ejecutivo. – tladuke

+0

Hmm ... No sabía sobre la opción -print0. Eso es _mucho_ más limpio. ¡Gracias! – Sbodd

0

xargs busca su entrada en fragmentos de tamaño razonable: lo que está viendo son totales para cada uno de esos fragmentos. Consulte la página de manual de xargs para conocer las formas de configurar su manejo de la entrada.

3

El programa xargs divide las cosas en lotes, para tener en cuenta los límites debido a la longitud máxima de una línea de comandos de Unix. Es aún más eficiente que ejecutar su subcomando de a uno por vez pero, para una larga lista de entradas, ejecutará el comando las veces suficientes para que cada "ejecución" sea lo suficientemente corta como para no causar problemas.

Debido a esto, es probable que vea una línea de salida por "lote" que xargs necesita para ejecutarse.

Debido a que puede que le resulte, la página hombre útil/interesante se puede encontrar en línea aquí: http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs


otra cosa a tener en cuenta (y esto puede ser un error tipográfico en su puesto o mi mala interpretación) es que tiene el "* .txt" sin emparejar/citado. Es decir, tiene

find . -name *.txt | xargs du -hc 

donde es probable que desee

find . -name \*.txt | xargs du -hc 

La diferencia es que la línea de comandos se puede ampliando el * en la lista de los nombres de archivo que coincidan ... en lugar de pasar el * en encontrar, que lo usará como un patrón.

0

Una solución alternativa es usar awk:

find . -name "*.txt" -exec ls -lt {} \; | awk -F " " 'BEGIN { sum=0 } { sum+=$5 } END { print sum }' 
7
find . -print0 -iname '*.txt' | du --files0-from=- 

y si usted quiere tener varias extensiones diferentes de buscar lo que es mejor hacer:

find . -type f -print0 | grep -azZEi '\.(te?xt|rtf|docx?|wps)$' | du --files0-from=- 
+0

Mucho más fácil de recordar que '-exec echo {}" = 0 ";'. no, espera. Eso no está bien. Uhhh '-exec echo -n {}" \ 0 "\;'. ¿No? '-exec echo $ # & @ * # (@! @ # $ @ # !!!' (Mucho mejor) – Stephen

+0

La primera forma en que aparece en la lista nunca llegará a la prueba '-iname * .txt' y al glob' * .txt' se expandirá antes de que se ejecute 'find' si tiene archivos' .txt' en su directorio de trabajo. – BroSlow

+0

Está en lo correcto. Gracias por señalar el error. Lo he corregido – OmnipotentEntity

3

Otra solución simple:

find . -name *.txt -print0 | xargs -0 du -hc 
+1

Para mejorar la calidad de su publicar, por favor incluya cómo/por qué su publicación resolverá el problema. –

0

Una solución alternativa es utilizar fiesta for bucle:

for i in `find . -name '*.txt'`; do du -hc $i | grep -v 'total'; done 

Esto es bueno para cuando necesita más control de lo que sucede en el ciclo.

Cuestiones relacionadas