¿Cómo encuentro archivos y totalizo sus tamaños?


12

Me gustaría encontrar una serie de archivos (basados ​​en una expresión comodín) y totalizar el uso de su disco.

Algo como esto:

$ find . -name 'flibble*' -ctime +90 -exec du -sh {} \;

2.1G    ./flibble_116.log
2.1G    ./flibble_83.log
2.1G    ./flibble_211040_157.log
2.1G    ./flibble3747_51.log

Este trabajo. Pero no produce el resultado que estoy buscando. Enumera el espacio utilizado por cada archivo, ya que findestá iterando a través de ellos.

Lo que quiero es el total dude todos los archivos encontrados.

Respuestas:


12

Solución

Al proporcionar la opción -c(o --total) a du(1), puede indicarle que produzca un total general. Si su implementación de du(1)admite cualquiera de estas opciones, puede lograr el efecto deseado con el siguiente comando:

$ find . -name 'flibble*' -ctime +90 -exec du -shc {} +

EDITAR: tenga en cuenta que si el número de archivos excede el número máximo de parámetros permitidos por su sistema, findaún puede ejecutarse commandvarias veces. Algunas implementaciones de du(1)también admiten la lectura de los nombres de archivo de un archivo, que no sufre la limitación mencionada:

$ find -name 'flibble*' -ctime +90 -print0 > filenames
$ du -shc --files0-from=filenames

Explicación

La diferencia entre la semántica de -exec command {} \;y -exec command {} +es la siguiente:

  • command {} \;se ejecuta commanduna vez por cada resultado de find. El nombre de ruta del resultado se pasa en lugar de {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} \;
    1
    2
    3
  • command {} +se ejecuta command, cuando todos los resultados han sido recuperados. Los nombres de ruta de los resultados se pasan en lugar de {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} +
    1 2 3

La -print0opción hace find(1)que se impriman los nombres de archivo encontrados en la salida estándar separada por el carácter nulo, y la --files0-fromopción hace du(1)que se lean los nombres de archivo separados por nulo. A diferencia del nuevo carácter de línea, el carácter nulo puede no aparecer en un nombre de archivo, por lo que la salida no es ambigua.

Para obtener más información sobre las opciones de du(1)y find(1), debe consultar las respectivas páginas de manual:

$ man du
$ man find

2
Puede terminar con múltiples totales si la cantidad de archivos es importante (1K +) debido a la limitación de la cantidad de argumentos de la línea de comando.
ychaouche

Puedo confirmar @ychaouche, tengo el problema al intentar evaluar el tamaño de más de 30k archivos.
Adrien H

Si eso es un problema, algunas implementaciones de du(1)también apoyan la lectura de los nombres de archivo de un archivo: find 1 2 3 -maxdepth 0 -print0 > filenames; du -shc --files0-from=filenames.
Witiko

4

Prueba esto:

du -c `find . -name 'flibble*' -ctime +90` | tail -1

El comando original está dando du un argumento, luego ejecutándolo, hasta que pasa por todos los argumentos. De esta manera, simplemente le está dando todos los argumentos a la vez, luego cortando los tamaños separados y dejando solo el total. Puede eliminar la tubería y la cola para mostrar el tamaño de cada archivo si lo desea.


Esto no producirá resultados correctos con nombres de ruta que contengan espacios. La forma correcta de hacer esto es usar la -exec du -c {} +opción de find, que pasará los nombres de ruta sin modificaciones du.
Witiko

4

Puedes probar esto:

find . -name 'flibble*' -ctime +90 -exec du -ch {} + | grep total

2

Me gustaría findimprimir el tamaño y usar otra herramienta para calcular el total:

find . -name 'flibble*' -ctime +90 -printf "%s\n" |
perl -lnE '$sum += $_} END {say $sum'

Si también quieres ver los nombres de los archivos:

find . -name 'flibble*' -ctime +90 -printf "%s\t%p\n" |
perl -apE '$sum += $F[0]} END {say $sum'

1

Un revestimiento que debería funcionar para obtener un total de Gigabyte en la mayoría de los sistemas:

echo "$(( ($(find . -name 'flibble*' -ctime +90 -type f -printf '%k+' )0)/1024/1024 )) GB"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.