Supongamos que hay un directorio de almacenamiento de imágenes, digamos, ./photos/john_doedentro del cual hay múltiples subdirectorios, donde residen ciertos archivos (digamos *.jpg). ¿Cómo puedo calcular un tamaño de resumen de esos archivos debajo de la john_doerama?
Lo intenté du -hs ./photos/john_doe/*/*.jpg, pero esto muestra solo archivos individuales. Además, esto solo rastrea el primer nivel de anidamiento del john_doedirectorio, como john_doe/june/, pero omite john_doe/june/outrageous/.
Entonces, ¿cómo podría atravesar toda la rama, resumiendo el tamaño de ciertos archivos?
files
directory
directory-structure
size
mbaitoff
fuente
fuente

LC_ALL=POSIXcomo prefijo a grep para un total como este:LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$-name, cambie el grep agrep -P "\ttotal$"o de lo contrario capturará todos los archivos que terminen en "total" también.bc, por lo que aquí es una solución más portátil:find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'me da el uso total de mis
.jpgarchivos en este directorio.Para lidiar con múltiples directorios, probablemente tenga que combinar esto de
findalguna manera.Puede encontrar ejemplos de comandos du útiles (también incluye
find)fuente
-Ropción en man7.org/linux/man-pages/man1/du.1.html . Y no creo que una opción recursiva ayude en este caso porque el shell está haciendo la expansión global antes de pasarle los argumentosdu.Principalmente, necesitas dos cosas:
-copción dedudecirle que produzca un gran total;**( instrucciones de activación ) ofind( ejemplo ) o para recorrer subdirectorios.fuente
findpuede devolver resultados erróneos.du -ch -- ./{dir1,dir2}/*.jpgodu -ch -- ./{prefix1*,prefix2*}.jpgArgument list too longerror al procesar aproximadamente 300k archivos de texto.getconf ARG_MAX. Si tiene más, deberá procesar los archivos uno por uno o por lotes con un bucle for.La respuesta final es:
e incluso una versión más rápida, no limitada por RAM, pero eso requiere GNU AWK con soporte bignum:
Esta versión tiene las siguientes características:
findespecificar los archivos que está buscandofindhace una simple combinación de comodines de nombres de archivo5.5K,176.7M, ...)| numfmt --to=sifuente
Las respuestas dadas hasta ahora no tienen en cuenta que la lista de archivos pasada de find a du puede ser tan larga que find divide automáticamente la lista en fragmentos, lo que resulta en múltiples ocurrencias de
total.Puede
grep total(¡locale!) Y resumir manualmente, o usar un comando diferente. AFAIK solo hay dos formas de obtener un gran total (en kilobytes) de todos los archivos encontrados por find:find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'Explicación
find . -type f -iname '*.jpg' -print0: Encuentre todos los archivos con la extensión jpg sin importar el caso (es decir, * .jpg, * .JPG, * .Jpg ...) y envíelos (terminados en nulo).xargs -r0 du -a: -r: Xargs llamaría al comando incluso sin pasar argumentos, lo que -r evita. -0 significa cadenas terminadas en nulo (no terminadas en nueva línea).awk '{sum+=$1} END {print sum}': Resuma los tamaños de archivo generados por el comando anteriorY para referencia, la otra forma sería
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-fuente
du --file0-fromtomó más tiempo porque lo ejecutó primero (efecto de almacenamiento en caché).xargs,du -ase pueden ejecutar varios , por lo que puede tener discrepancias si hay enlaces duros.Si la lista de archivos es demasiado grande y no se puede pasar a una sola invocación de
du -c, en un sistema GNU, puede hacer lo siguiente:(tamaño expresado en número de bloques de 512 bytes). Al igual
duque trata de contar enlaces duros solo una vez. Si no le interesan los enlaces duros, puede simplificarlo a:Si desea el tamaño en lugar del uso del disco, reemplácelo
%bcon%s. El tamaño se expresará en bytes.fuente
-bash: bc: command not foundCentos - Linux 2.6.32-431.el6.x86_64bces un comando POSIX no opcional.Las soluciones mencionadas hasta ahora son ineficientes (exec es costoso) y requieren trabajo manual adicional para sumar si la lista de archivos es larga o no funcionan en Mac OS X. La siguiente solución es muy rápida, debería funcionar en cualquier sistema, y produce la respuesta total en GB (elimine a / 1024 si desea ver el total en MB):
find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'fuente
-inametampoco-lsson estándar / portátiles, por lo que tampoco funcionará en ningún sistema . Tampoco funcionará correctamente si hay nombres de archivo u objetivos de enlace simbólico que contengan caracteres de nueva línea.Mejorar la excelente respuesta de SHW para que funcione con cualquier configuración regional, como Zbyszek ya señaló en su comentario:
fuente
du atraviesa naturalmente la jerarquía de directorios y awk puede realizar el filtrado, por lo que algo como esto puede ser suficiente:
Esto funciona sin GNU.
fuente
statllamada para archivos que no corresponden al patrón buscado.