Größe aller Dateien einer bestimmten Erweiterung in einem Verzeichnisbaum

16

Ich möchte die Größe der Datei mit der Erweiterung .o (Objektdatei) in meinem Basisordner erfahren.

Ich kann alle Objektdateien mit finden

find . -name '*.o'

Wie kann ich nun die Gesamtgröße dieser Dateien berechnen?

alhelal
quelle

Antworten:

24

Du suchst nach Rohren ( |). Sie sind eine Möglichkeit, mehrere Befehle zu verbinden und die Ausgabe eines Befehls als Eingabe an einen anderen zu übergeben. In diesem Fall möchten Sie alle Dateinamen übergeben, die Sie als Eingabe finden du(berechnet die Größe). Da jedoch duDateinamen erwartet werden und die Ergebnisse findnur eine Textliste sind (ja, der Text besteht aus Dateinamen, dukann aber nicht wissen, dass nur Text angezeigt wird), müssen Sie so etwas wie xargsdas verwenden, was jeweils benötigt wird Textzeile, behandeln Sie sie als Dateinamen und übergeben Sie diese an du. Wenn wir all dies zusammenfassen, erhalten wir:

find . -name "*.o" | xargs du -sch
  • du solltest immer die Muster zitieren, die Sie geben find(wie ich oben tat:) "*.o". Wenn Sie dies nicht tun, erweitert die Shell das Feld *.oauf die Namen aller übereinstimmenden Dateien im aktuellen Verzeichnis. In diesem Fall hat es nur funktioniert, weil Sie keine passenden Dateien hatten.

  • Die -schFlags für dusind in dokumentiertman 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
    

Beachten Sie jedoch, dass dies für Dateinamen mit Leerzeichen fehlschlägt. Dies wird mit ziemlicher Sicherheit kein Problem für Objektdateien sein. Wenn Sie sich jedoch in Zukunft auch mit Leerzeichen befassen müssen, verwenden Sie:

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

Das -print0machtfind gedruckt werden NULL-getrennte Leitungen und die -0Marken xargsnehmen solche Linien als Eingabe.

Alternativ können Sie haben find die Größen selbst ausdrucken und dann summieren:

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

Dies wird auch das von @Serg in erwähnte Problem umgehen den Kommentaren dem zu viele Argumente und der Befehl in separate Befehle unterteilt ist.


Wenn Sie bash(wahrscheinlich) verwenden, gibt es einen einfacheren Weg:

shopt globstar 
du -sch **/*.o

Mit diesem shopt globstarBefehl werden **alle Dateien und / oder Unterverzeichnisse abgeglichen. Nach dem Aktivieren**/*.o werden alle Dateien (und Verzeichnisse) abgeglichen .o, deren Name auf endet , damit wir das direkt weitergeben können du.

Beachten Sie, dass im Gegensatz zum findAnsatz keine versteckten Dateien gefunden werden (diejenigen, deren Name mit einem beginnt .). Um diese auch abzugleichen, gehen Sie wie folgt vor:

shopt -s dotglob globstar
du -sch **/*.o
terdon
quelle
Es gibt ein kleines Problem mit dem ersten. Es gibt so etwas wie MAXARGS. Es wird also mehrere Iterationen von geben du, und es werden mehrere totalZeilen erzeugt. Beispiel: paste.ubuntu.com/23092752
Sergiy Kolodyazhnyy
@ Serg wahr. Ich habe eine weitere Option hinzugefügt, die dies vermeidet.
Terdon
8

Verwenden Sie -exec flag, um den duBefehl mit ;(Bedeutung pro Datei) auszuführen.

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

Beispielausgabe:

$ 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

findist rekursiv - was bedeutet, dass alle Unterverzeichnisse durchsucht werden. Wenn Sie nur die Gesamtzahl aller *.oDateien im aktuellen Verzeichnis abrufen möchten , tun Sie dies einfach

du -b -c *.o
Sergiy Kolodyazhnyy
quelle
0

mit perl:

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

Größe aller nicht ausgeblendeten PDF-Dateien im aktuellen Verzeichnis.

verrückt machen
quelle
1
OK, aber das OP sucht nach .oDateien und sie könnten sich in Unterverzeichnissen befinden. Sie können auch ein }{Vorher hinzufügen print $sum, um zu vermeiden, dass die Summe bei jeder Iteration gedruckt wird. Wir wollen nur den letzten.
Terdon