2009-03-01 16 views
51

Sto provando a calcolare la dimensione totale in byte di tutti i file (in un albero di directory) che corrispondono a un modello di nome file usando solo la shell. Questo è quello che ho finora:Calcola la dimensione dei file nella shell

find -name * .undo -exec stat -c% s {} \; | awk '{total + = $ 1} END {print total}'

C'è un modo più semplice per farlo? Sento che dovrebbe esserci un interruttore o un interruttore semplice che fa questo per me, ma non riesco a trovarne uno.

Per essere chiari voglio file totale di un modello da nessuna parte sotto un albero di directory che significa

du -bs * .undo

non funzionerà, perché corrisponde solo i file nella directory corrente.

+0

In ogni caso, 'du' (o' ls') non funzionerà sopra alcune migliaia di file (errore "Argument list too long"). –

risposta

94

Prova:

find . -name "*.undo" -ls | awk '{total += $7} END {print total}' 

Sul mio sistema la dimensione del file è il settimo campo nel find -ls uscita. Se l'uscita find … -ls è diversa, regolare.

In questa versione, utilizzare le informazioni di directory esistenti (dimensione del file) e la funzione ls integrata di find dovrebbe essere efficiente, evitando creazioni di processi o file i/o.

+2

Questo dovrebbe funzionare, ma l'opzione -ls per trovare e awk è eccessiva per questa attività. –

+9

no non eccedere affatto. – vladr

+4

Aggiungerei "-type f" al comando find per impedire il totale errato se ci sono directory che corrispondono a "* .undo" glob. –

-3

Controllare il comando du (utilizzo del disco).

18
du -c *pattern* 

Questo stamperà il totale sull'ultima riga di output.

+1

E usare la coda per tagliare tutto tranne l'ultima linea. +1. =] – strager

+6

Questo troverà solo i file che corrispondono al modello nella directory corrente, non è vero? –

+0

È possibile utilizzare uno schema come '*/*. Undo' ... sebbene questo trovi solo i file con l'estensione di annullamento con una profondità di una cartella ... inoltre non ne troverà nessuno nella directory corrente. – Kasapo

8
find -name '*.undo' -exec wc -c {} + | tail -n 1 

dovrebbe dare il numero totale effettivo di byte nei file, se non si dispone di troppi file (dove "troppi" sta per essere davvero un gran numero, probabilmente nell'ordine delle migliaia). O se vuoi solo ottenere il numero da solo,

find -name '*.undo' -exec wc -c {} + | tail -n 1 | cut -d' ' -f 1 
+0

È necessario indicare "* .undo", "* .undo", \ *. Undo o simile; altrimenti, si otterranno risultati errati se esiste un file.undo nella directory corrente. – ephemient

5

Python fa parte della maggior parte delle distribuzioni Linux.

import os 
import fnmatch 
size= 0 
for path, dirs, files in os.walk('.'): 
    for f in files: 
     if fnmatch.fnmatch(f,'*.py'): 
      fileSize= os.path.getsize(os.path.join(path,f)) 
      print f, fileSize 
      size += fileSize 
print size 

Long, ma perfettamente chiaro ed altamente estensibile.

35

Con zsh, è possibile utilizzare il globbing esteso a fare:.

du -c **/* annullare

+4

E anche Fish and Bash 4.0! – ephemient

+5

E' du -ch **/*. undo' per ottenere dimensioni dei file leggibili dall'uomo ... – student

22
find -name *.undo -print0 | du -hc --files0-from=- 
+0

Questo elenco Tutti i file. C'è un modo per mostrare solo il totale? Indipendentemente, sto pensando che questo sia un candidato 'risposta corretta'. –

+3

Mi piace perché mostra la dimensione 'leggibile'. @Tyler Collier per mostrare solo il totale usa tail: 'find -type f -name '* .undo' -print0 | du -hc --files0-from = - | tail -n 1' –

+0

Questa è la migliore risposta che abbia mai visto per fare questo su linux ... io ts esegue anche circa 1000 volte più velocemente di qualsiasi altra risposta che ho visto, poiché du su un file viene eseguito così velocemente, in più fornisce output in termini leggibili dall'uomo – Myforwik

3
find -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1 

messo insieme da gerdemb 's ed i contributi di Strager. L'utilizzo di du -cb dovrebbe visualizzare i byte.

9

Anche io ho visto questo problema (solo un anno dopo ...) - ho appena trovato questa pagina.

Qualcosa che ho trovato funziona (per me) è la seguente:

find /mnt/iso -name *.avi -printf "%s\n" | paste -sd+ - | bc 

Ciò restituirà la dimensione totale di tutti i file .avi in ​​tutte le sotto-cartelle sotto/mnt/iso

devo dare credito a radoulov per il comando incolla - vedi questa pagina: Shell command to sum integers, one per line?

solo aggiungere - nel caso in cui una cartella corrisponde al termine di ricerca - è una buona idea usare -type f nel comando find pure.

0

Che ne dici di questo semplice.

find ./ -name *.undo | xargs wc 
2

Io uso du comando come questo per ottenere il numero unico:

du file_list | awk '{s+=$1} END {print s}' 
0

In alternativa, si può semplicemente fare questo:

dir=$1 

for file in $dir/* ; do 

length_file=`stat -c %s $file` 
echo "File $file has length $length_file" 
length_total=`expr $length_total + $length_file` 

done 

echo "Total length: $length_total ." 

Dove stat visualizza uno stato del file o del file system . L'argomento -c significa utilizzare il formato specificato anziché quello predefinito e la sequenza di formati $ s consente la visualizzazione della dimensione totale dei byte.

expr 

Valuta solo un'espressione.

0

Perl one-liner:

find . -name "*.undo" -ls | perl -lane '$t += $F[6]; END{print $t}' 

L'array @F autosplit dalle ore indice $F[0] mentre i campi awk iniziano con $ 1, quindi $F[6] è usato al posto di di awk $7

0

du -c | awk '/./{line=$0} END {print $ 1}'

0

Penso che la versione con xargs possa essere imroved (semplificata) ls -1 * .undo | xargs wc

Problemi correlati