2014-02-24 9 views
16

Ich möchte einen Befehl find ausführen, der eine bestimmte Liste von Dateien findet und dann diese Liste von Dateien durchläuft, um einige Operationen auszuführen. Ich möchte auch die Gesamtgröße aller Dateien in dieser Liste finden.Ermitteln der Gesamtgröße einer Liste von Dateien unter UNIX

Ich möchte die Liste der Dateien zuerst machen, dann machen Sie die anderen Operationen. Gibt es einen einfachen Weg, um nur die Gesamtgröße aller Dateien in der Liste zu melden?

Im Grunde versuche ich unten einen Einzeiler für die 'total_size' Variable im Code-Schnipsel zu finden:

#!/bin/bash 
loc_to_look='/foo/bar/location' 

file_list=$(find $loc_to_look -type f -name "*.dat" -size +100M) 

total_size=??? 

echo 'total size of all files is: '$total_size 

for file in $file_list; do 
     # do a bunch of operations 
done 
+1

Sie können "\ n% s% p" verwenden '' printf in Ihrem 'find' Befehl die Namen + Größe zu zeigen. – fedorqui

+0

@fedorqui Wenn ihre Version von 'find'' -printf' unterstützt. Eine Form von '-exec stat -f'% z '{} \; '(abhängig von der Implementierung von' stat 'in Ihrem System) würde ebenfalls funktionieren. – chepner

+0

@fedorqui: außerdem müssten Sie dann die Dateinamen und Größen vor der for-Schleife aufteilen ... – sanmiguel

Antwort

25

Sie sollten einfach in der Lage sein $file_list zu du weitergeben müssen:

du -ch $file_list | tail -1 | cut -f 1 

du Optionen:

  • -c d isplay insgesamt
  • menschenlesbar (d. h. 17M)

du einen Eintrag für jede Datei, gefolgt von der Gesamt (mit -c) drucken möchten, so verwenden wir tail -1 nur die letzte Zeile zu trimmen und cut -f 1 diese Linie nur die erste Spalte zu trimmen.

+0

danke @sanmiguel! Ich gebe den Befehl in Backticks für die Variable: D – HotDogCannon

+0

Ah ja, das könnte auch helfen ... – sanmiguel

+1

Dies ist eine nette Antwort, aber bitte denken Sie daran, dass 'du' die tatsächliche Festplattennutzung auf ein Vielfaches von (normalerweise) 4 aufrundet KB statt der logischen Dateigröße. 'für i in {0..9}; do echo -n $ i> $ i.txt; erledigt; du -ch * .txt' => 40K total' statt '10 total'. – nodakai

1

Dieser Code fügt von den treuen ls für alle Dateien alle Bytes (es alle Verzeichnisse ausschließt ... anscheinend sie 8kb pro Ordner/Verzeichnis)

cd /; find -type f -exec ls -s \; | awk '{sum+=$1;} END {print sum/1000;}' 

Hinweis: als root ausführen . Ergebnis in Megabyte.

11

Die hier erläuterten Methoden haben einen versteckten Fehler. Wenn die Dateiliste lang ist, überschreitet sie das Limit der Shell-Befehlsgröße. Bessere verwenden Sie diese mit du:

Find produziert null endete Dateiliste, du nimmt es von Stdin und zählt. Dies ist unabhängig von der Shell-Befehlsgrößenbeschränkung. Natürlich können Sie einige Switches hinzufügen, um die logische Dateigröße zu erhalten, weil Sie standardmäßig angegeben haben, wie viel Speicherplatz die Dateien benötigen.

Aber ich denke, es ist keine Frage für Programmierer, sondern für Unix-Admins :) dann für stackoverflow das ist out of topic.

+2

Dies ist bei weitem die beste Antwort. Keine Notwendigkeit für awk oder Shell-Variablen. – EMiller

0

ls -l | tr -s '' | cut -d '' -f ist etwas, was ich oft benutze.

Das 5. Feld ist die Größe. Setzen Sie diesen Befehl in eine for-Schleife und fügen Sie die Größe zu einem Akkumulator hinzu und Sie erhalten die Gesamtgröße aller Dateien in einem Verzeichnis. Leichter das Lernen von AWK. Außerdem können Sie im Befehlsersatzteil grep verwenden, um das zu begrenzen, wonach Sie suchen (^ - für Dateien usw.).

gesamt = 0

für Größe in $ (ls -l | tr -s '' | cut -d '' -f 5); do gesamt = $ (($ {total} + $ {size})); getan

echo $ {total}

+0

Antwort kann korrekt sein, aber für andere zu verstehen, fügen Sie bitte etwas Text, um in schöner Weise zu beschreiben. –

Verwandte Themen