Come trovare la dimensione totale del file raggruppata per estensione


12

Lavoro su un cluster condiviso con altri colleghi. Il disco rigido è limitato (ed è stato pieno in alcune occasioni), quindi ogni tanto pulisco la mia parte. Voglio farlo rapidamente, quindi fino ad ora lo faccio facendo un elenco di file più grandi di 100 MB più vecchi di 3 mesi e vedo se ne ho ancora bisogno.

Ma ora sto pensando che potrebbe esserci una cartella con> 1000 file più piccoli che mi mancano, quindi voglio ottenere un modo semplice per vedere se questo è il caso. Dal modo in cui generi i dati, sarebbe utile ottenere un elenco delle dimensioni totali per estensione. Nel contesto di questa domanda, "estensione" è tutto dietro all'ultimo punto nel nome del file.

Supponiamo che io abbia più cartelle con più file:

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

È possibile creare un elenco di dimensioni file totali per estensione, in questo modo:

bmp 70 kiB
jpg 28 kiB

Non mi importa dei file senza estensione, quindi possono essere ignorati o inseriti in una categoria.

Ho già sfogliato pagine man di ls, due find, ma non so quale sia lo strumento giusto per questo lavoro ...


Questa domanda non sarebbe sbagliata su codegolf.stackexchange.com :)
Doug McLean

@DougMcLean: sei invitato a pubblicarlo lì. ;)

Risposte:


16

Su 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 stesso con perl, evitando l' -printfestensione di GNU find(usando ancora un'estensione GNU -print0, ma questa è oggi ampiamente supportata):

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{$_}, $_;
      }
    }'

Dà un output come:

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

Se vuoi KiB, MiB... suffissi, pipe a numfmt --to=iec-i --suffix=B.

%b*512fornisce l'utilizzo del disco, ma si noti che se i file sono collegati più volte più volte, verranno conteggiati più volte in modo da poter vedere una discrepanza rispetto ai dureport.


Non riesce su MacOS (trova: -printf: primario o operatore sconosciuto)
MichaelCodes

1
@MichaelCodes, sì, -printfè specifico di GNU find, motivo per cui ho detto su un sistema GNU .
Stéphane Chazelas,

@MichaelCodes, vedi modifica con perlun'alternativa che dovrebbe funzionare anche su macOS.
Stéphane Chazelas,

Che cosa è 1,4,2,17? La quantità di file per ogni tipo?
Jorge Cornejo Bellido,

3

Ecco un'altra soluzione:

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 che ottiene le estensioni è:

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

Quindi cerca i file con un'estensione e stampalo anche sullo schermo:

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

Quindi vogliamo mantenere l'estensione e il totale:

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

e tienilo sulla stessa linea:

paste - -

Funziona su MacOS.
MichaelCodes

2

Non carino come la soluzione di Stephane, ma potresti provarci

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

dove devi eseguirlo per ogni tipo di file.


1
Ciò presuppone che ci siano abbastanza pochi file png che solo uno du eseguire chiamata. Con GNU xargs, vorresti aggiungere il -rflag in modo che du non venga eseguito quando non c'è nessun file (altrimenti, finiresti con l'uso del disco della directory corrente). Potresti voler aggiungere un -type fo ! type dper evitare di contare i file che si trovano nelle directory il cui nome termina .png.
Stéphane Chazelas,

questo cerca solo un'estensione specifica.
Rahul,

Questo è quello che ho scritto. Uno ha dovuto avvolgerlo in uno script che scorre su tutte le estensioni applicabili al fine di ottenere una soluzione "completa".
Contromodalità
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.