Tamaño de todos los archivos de cierta extensión en un árbol de directorios

16

Quiero saber el tamaño del archivo con extensión .o (archivo de objeto) en mi carpeta Inicio.

Puedo encontrar todos los archivos de objetos usando

find . -name '*.o'

¿Cómo puedo calcular ahora el tamaño total de esos archivos?

alhelal
fuente

Respuestas:

24

Estás buscando pipas ( |). Son una forma de conectar múltiples comandos y pasar la salida de un comando como entrada a otro. En este caso, desea pasar todos los nombres de archivo que encuentre como entrada du(que calcula el tamaño). Sin embargo, dado duque los nombres de archivo y los resultados findson solo una lista de texto (sí, el texto consiste en nombres de archivo, pero duno puede saberlo, todo lo que ve es texto), debe usar algo como xargslo que tomará cada línea de texto, trátelo como un nombre de archivo y páselo a du. Al unir todo esto, obtenemos:

find . -name "*.o" | xargs du -sch
  • siempre debes citar los patrones que le das find(como lo hice anteriormente "*.o"). Si no lo hace, el shell expandirá *.olos nombres de los archivos coincidentes en el directorio actual. Funcionó en este caso solo porque no tenía archivos coincidentes.

  • Las -schbanderas para duestán documentadas en man du:

    -c, --total
          produce a grand total
    -h, --human-readable
          print sizes in human readable format (e.g., 1K 234M 2G)
    -s, --summarize
          display only a total for each argument
    

Sin embargo, tenga en cuenta que esto fallará para los nombres de archivo que contienen espacios en blanco. Esto seguramente no será un problema para los archivos de objetos, pero en el futuro, si también necesita lidiar con espacios, use:

find . -name "*.o" -print0 | xargs -0 du -sch

Las -print0marcas findimprimen líneas separadas por NULL y las -0marcas xargstoman tales líneas como entrada.

Alternativamente, puede findimprimir los tamaños en sí y luego sumarlos:

find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'

Esto también evitará el problema mencionado por @Serg en los comentarios donde hay demasiados argumentos y el comando se divide en comandos separados.


Si está usando bash(probablemente lo esté), hay una manera más simple:

shopt globstar 
du -sch **/*.o

El shopt globstarcomando hace **coincidir todos los archivos y / o más subdirectorios. Después de habilitarlo, **/*.ocoincidirá con todos los archivos (y directorios) cuyo nombre termine .o, para que podamos pasarlo directamente a du.

Tenga en cuenta que, a diferencia del findenfoque, esto no coincidirá con los archivos ocultos (aquellos cuyo nombre comienza con a .). Para combinarlos también, haga:

shopt -s dotglob globstar
du -sch **/*.o
terdon
fuente
Hay un pequeño problema con el primero. Existe tal cosa como MAXARGS. Entonces habrá múltiples iteraciones de du, y producirá múltiples totallíneas. Aquí hay un ejemplo: paste.ubuntu.com/23092752
Sergiy Kolodyazhnyy
@Serg cierto. Agregué otra opción que evita eso.
terdon
8

Usa la -exec bandera para correrdu comando con ;(significado por cada archivo)

find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}' 

Salida de muestra:

$ find . -name "*.txt"  -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'                                     
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes

findes recursivo, lo que significa que recorre todos los subdirectorios. Si solo desea obtener el total de todos los *.oarchivos en el directorio actual, simplemente haga

du -b -c *.o
Sergiy Kolodyazhnyy
fuente
0

con perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Tamaño de todos los archivos PDF no ocultos en el directorio actual.

agrietado
fuente
1
OK, pero el OP está buscando .oarchivos y podrían estar en subdirectorios. También es posible que desee agregar un }{antes print $sumpara evitar imprimir la suma de cada iteración. Solo queremos el último.
terdon