Cómo encontrar el tamaño de archivo total agrupado por extensión


12

Trabajo en un clúster compartido con otros colegas. El disco duro es limitado (y ha estado lleno en algunas ocasiones), así que ocasionalmente limpio mi parte. Quiero hacer esto rápidamente, así que hasta ahora lo hago haciendo una lista de archivos de más de 100 MB de más de 3 meses, y veo si todavía los necesito.

Pero ahora estoy pensando que podría haber una carpeta con> 1000 archivos más pequeños que echo de menos, así que quiero obtener una manera fácil de ver si este es el caso. Por la forma en que genero datos, sería útil obtener una lista del tamaño total por extensión. En el contexto de esta pregunta, 'extensión' como todo lo que está detrás del último punto en el nombre del archivo.

Supongamos que tengo varias carpetas con múltiples archivos:

folder1/file1.bmp   40 kiB
folder1/file2.jpg   20 kiB
folder2/file3.bmp   30 kiB
folder2/file4.jpg    8 kiB

¿Es posible hacer una lista del tamaño total de archivos por extensión de archivo, así:

bmp 70 kiB
jpg 28 kiB

No me importan los archivos sin extensión, por lo que pueden ignorarse o colocarse en una categoría.

Ya revisé las páginas de manual de ls, duy find, pero no sé cuál es la herramienta adecuada para este trabajo ...


Esta pregunta no estaría mal en codegolf.stackexchange.com :)
Doug McLean

@DougMcLean: puedes publicarlo allí. ;)

Respuestas:


16

En un sistema GNU:

find . -name '?*.*' -type f -printf '%b.%f\0' |
  awk -F . -v RS='\0' '
    {s[$NF] += $1; n[$NF]++}
    END {for (e in s) printf "%15d %4d %s\n", s[e]*512, n[e], e}' |
  sort -n

O lo mismo con perl, evitando la -printfextensión de GNU find(todavía usando una extensión de GNU -print0, pero esta es más ampliamente compatible hoy en día):

find . -name '?*.*' -type f -print0 |
  perl -0ne '
    if (@s = stat$_){
      ($ext = $_) =~ s/.*\.//s;
      $s{$ext} += $s[12];
      $n{$ext}++;
    }
    END {
      for (sort{$s{$a} <=> $s{$b}} keys %s) {
        printf "%15d %4d %s\n",  $s{$_}<<9, $n{$_}, $_;
      }
    }'

Da una salida como:

          12288    1 pnm
          16384    4 gif
         204800    2 ico
        1040384   17 jpg
        2752512   83 png

Si quieres KiB, MiB... sufijos, pipa a numfmt --to=iec-i --suffix=B.

%b*512proporciona el uso del disco, pero tenga en cuenta que si los archivos están vinculados varias veces, se contarán varias veces para que pueda ver una discrepancia con los duinformes.


Falla en MacOS (buscar: -printf: primario u operador desconocido)
MichaelCodes

1
@MichaelCodes, sí, -printfes específico de GNU find, por eso lo dije en un sistema GNU .
Stéphane Chazelas

@MichaelCodes, vea editar con una perlalternativa que debería funcionar incluso en macOS.
Stéphane Chazelas

¿Qué es 1,4,2,17? ¿La cantidad de archivos para cada tipo?
Jorge Cornejo Bellido

3

Aquí hay otra solución:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u | xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \; | egrep "^\.[a-zA-Z0-9]+$|total$" | uniq | paste - -

La parte que obtiene las extensiones es:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u

Luego busque los archivos con una extensión e imprímalos también en la pantalla:

xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \;

A continuación queremos mantener la extensión y el total:

egrep "^\.[a-zA-Z0-9]+$|total$" | uniq

y mantenlo en la misma línea:

paste - -

Funciona en MacOS.
MichaelCodes

2

No es tan bueno como la solución de Stephane, pero podrías intentar

find . -type f -name "*.png" -print0 | xargs -0r du -ch | tail -n1

donde debe ejecutar esto para cada tipo de archivos.


1
Eso supone que hay suficientes archivos png que solo duse ejecuta una invocación. Con GNU xargs, desearía agregar el -rindicador para que no se ejecute cuando no hay archivo (de lo contrario, terminaría con el uso del disco del directorio actual). Es posible que desee agregar un -type fo ! type dpara evitar contar los archivos que están en directorios cuyo nombre termina en .png.
Stéphane Chazelas

esto solo busca una extensión específica.
Rahul

Eso es lo que escribí. Uno tenía que envolverlo en un script que itera sobre todas las extensiones aplicables para obtener una solución "completa".
contramode
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.