Come posso trovare i file e totalizzarne le dimensioni?


12

Vorrei trovare una serie di file (basati su un'espressione jolly) e totalizzare il loro utilizzo del disco.

Qualcosa come questo:

$ 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

Questo lavoro. Ma non produce il risultato che sto cercando. Elenca lo spazio utilizzato da ciascun file, così come lo findsta ripetendo.

Quello che voglio è il totale dudi tutti i file trovati.

Risposte:


12

Soluzione

Fornendo l'opzione -c(o --total) a du(1), è possibile dargli istruzioni per produrre un totale complessivo. Se l'implementazione di du(1)supporta una di queste opzioni, è possibile ottenere l'effetto desiderato utilizzando il comando seguente:

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

EDIT: Notare che se il numero di file supera il numero massimo di parametri consentiti dal sistema, findpotrebbe comunque essere eseguito commandpiù volte. Alcune implementazioni du(1)supportano anche la lettura dei nomi di file da un file, che non risente della menzionata limitazione:

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

Spiegazione

La differenza tra la semantica di -exec command {} \;e -exec command {} +è la seguente:

  • command {} \;viene eseguito commanduna volta per ogni risultato di find. Il percorso del risultato viene passato invece di {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} \;
    1
    2
    3
    
  • command {} +viene eseguito commandquando tutti i risultati sono stati recuperati. I percorsi dei risultati vengono passati invece di {}.

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

L' -print0opzione provoca la find(1)stampa dei nomi dei file trovati nell'output standard separato dal carattere null e l' --files0-fromopzione ha causato la du(1)lettura dei nomi dei file separati da null. A differenza del nuovo carattere di riga, il carattere null potrebbe non apparire in un nome file, quindi l'output non è ambiguo.

Per ulteriori informazioni sulle opzioni di du(1)e find(1), è necessario consultare le rispettive manpage:

$ man du
$ man find

2
Potresti finire con più totali se il numero di file è importante (1K +) a causa della limitazione del numero di argomenti della riga di comando.
ychaouche,

Posso confermare @ychaouche, ho riscontrato il problema durante il tentativo di valutare la dimensione di oltre 30k file.
Adrien H,

Se questo è un problema, alcune implementazioni di du(1)supportano anche la lettura i nomi dei file da un file: find 1 2 3 -maxdepth 0 -print0 > filenames; du -shc --files0-from=filenames.
Witiko,

4

Prova questo:

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

Il comando originale sta dando du un argomento, quindi eseguendolo, fino a quando non passa attraverso tutti gli argomenti. In questo modo, stai semplicemente dando tutti gli argomenti contemporaneamente, quindi tagliando le dimensioni separate e lasciando solo il totale. Puoi rimuovere la pipa e la coda per mostrare le dimensioni di ciascun file, se lo desideri.


Ciò non produrrà risultati corretti con percorsi che contengono spazi. Il modo giusto per farlo è usare l' -exec du -c {} +opzione di find, che passerà inalterati i nomi dei percorsi du.
Witiko,

4

Puoi provare questo:

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

2

Avrei dovuto findstampare le dimensioni e utilizzare un altro strumento per calcolare il totale:

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

Se vuoi vedere anche i nomi dei file:

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

1

Un liner che dovrebbe funzionare per ottenere un totale di Gigabyte sulla maggior parte dei sistemi:

echo "$(( ($(find . -name 'flibble*' -ctime +90 -type f -printf '%k+' )0)/1024/1024 )) GB"
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.