Dimensione di tutti i file di una determinata estensione in un albero di directory


16

Voglio conoscere la dimensione del file con estensione .o (file oggetto) nella mia cartella Home.

Posso trovare tutti i file oggetto usando

find . -name '*.o'

Come posso ora calcolare la dimensione totale di quei file?

Risposte:


24

Stai cercando pipe ( |). Sono un modo per collegare più comandi e passare l'output di un comando come input a un altro. In questo caso, vuoi passare tutti i nomi dei file che trovi come input du(che calcola le dimensioni). Tuttavia, poiché si duaspetta che i nomi dei file e i risultati findsiano solo un elenco di testo (sì, il testo è costituito da nomi di file, ma dunon si può sapere che tutto ciò che vede è il testo), è necessario utilizzare qualcosa del tipo xargsche prenderà ciascuno riga di testo, trattalo come un nome di file e passalo a du. Mettendo tutto questo insieme, otteniamo:

find . -name "*.o" | xargs du -sch
  • dovresti sempre citare gli schemi a cui dai find(come ho fatto sopra:) "*.o". In caso contrario, la shell espanderà *.oi nomi dei file corrispondenti nella directory corrente. In questo caso ha funzionato solo perché non c'erano file corrispondenti.

  • I -schflag per dusono documentati in 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
    

Si noti, tuttavia, che ciò non avrà esito positivo per i nomi di file contenenti spazi bianchi. Questo non sarà quasi certamente un problema per i file oggetto, ma in futuro, se devi anche occuparti degli spazi, usa:

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

I -print0marchi findstampano linee NULL separati e -0marchi xargsprendono tali linee come input.

In alternativa, è possibile findstampare le dimensioni stesse e quindi sommarle:

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

Ciò aggirerà anche il problema menzionato da @Serg nei commenti in cui vi sono troppi argomenti e il comando è suddiviso in comandi separati.


Se stai usando bash(probabilmente lo sei), c'è un modo più semplice:

shopt globstar 
du -sch **/*.o

Il shopt globstarcomando fa **corrispondere tutti i file e o più sottodirectory. Dopo averlo abilitato, **/*.ocorrisponderà a tutti i file (e directory) il cui nome termina .o, in modo da poterlo passare direttamente a du.

Si noti che, a differenza finddell'approccio, questo non corrisponderà ai file nascosti (quelli il cui nome inizia con a .). Per abbinare anche quelli, fai:

shopt -s dotglob globstar
du -sch **/*.o

C'è un piccolo problema con il primo. Esistono MAXARGS. Quindi ci saranno più iterazioni di du, e produrrà più totallinee. Ecco un esempio: paste.ubuntu.com/23092752
Sergiy Kolodyazhnyy,

@Serg true. Ho aggiunto un'altra opzione che lo evita.
terdon,

8

Usa -exec flag per eseguire il ducomando con ; (significato per ogni file)

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

Uscita campione:

$ 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

findè ricorsivo, ovvero attraversa tutte le sottodirectory. Se vuoi solo ottenere il totale di tutti i *.ofile nella directory corrente, fallo

du -b -c *.o

0

con perl:

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

Dimensione di tutti i file PDF non nascosti nella directory corrente.


1
OK, ma l'OP sta cercando i .ofile e potrebbero trovarsi in sottodirectory. Potresti anche voler aggiungere un }{prima print $sumper evitare di stampare la somma per ogni iterazione. Vogliamo solo l'ultimo.
terdon,
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.