Angenommen, es gibt ein Bildspeicherverzeichnis ./photos/john_doe
, in dem sich mehrere Unterverzeichnisse befinden, in denen sich beispielsweise viele bestimmte Dateien befinden *.jpg
. Wie kann ich eine Gesamtgröße dieser Dateien unterhalb des john_doe
Zweigs berechnen ?
Ich habe es versucht du -hs ./photos/john_doe/*/*.jpg
, aber dies zeigt nur einzelne Dateien. Außerdem verfolgt dies nur die erste Verschachtelungsebene des john_doe
Verzeichnisses, john_doe/june/
überspringt jedoch john_doe/june/outrageous/
.
Wie könnte ich also den gesamten Zweig durchlaufen und die Größe bestimmter Dateien aufsummieren?
files
directory
directory-structure
size
mbaitoff
quelle
quelle
LC_ALL=POSIX
als Präfix hinzufügen, um immer wie folgt nach totalLC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
-name
, ändern Sie die Option grep in.grep -P "\ttotal$"
Andernfalls werden alle Dateien erfasst, die ebenfalls mit "total" enden.bc
, so ist hier eine tragbare Lösung:find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'
gibt mir die Gesamtnutzung meiner
.jpg
Dateien in diesem Verzeichnis.Um mit mehreren Verzeichnissen umgehen zu können, müssten Sie dies wahrscheinlich mit etwas anderem kombinieren
find
.Möglicherweise sind Beispiele für du-Befehle hilfreich (enthält auch
find
).quelle
-R
Option angezeigt . Und ich glaube nicht, dass eine rekursive Option in diesem Fall helfen würde, da die Shell die Glob-Erweiterung ausführt, bevor die Argumente an übergeben werdendu
.In erster Linie benötigen Sie zwei Dinge:
-c
Optiondu
, es zu sagen, um eine Gesamtsumme zu produzieren;**
( Aktivierungsanweisungen ) oderfind
( Beispiel ) oder zum Durchlaufen von Unterverzeichnissen.quelle
find
fehlerhaften Ergebnissen führen kann.du -ch -- ./{dir1,dir2}/*.jpg
oderdu -ch -- ./{prefix1*,prefix2*}.jpg
Argument list too long
beim Verarbeiten von ca. 300k Textdateien Fehler bekommen.getconf ARG_MAX
. Wenn Sie mehr haben, müssen Sie die Dateien einzeln oder stapelweise mit einer for-Schleife verarbeiten.Die ultimative Antwort lautet:
und noch schnellere Version, nicht durch RAM begrenzt, sondern benötigt GNU AWK mit Bignum-Unterstützung:
Diese Version hat die folgenden Funktionen:
find
zum Angeben der gesuchten Dateienfind
führt einen einfachen Wildcard-Abgleich von Dateinamen durch5.5K
,176.7M
, ...)| numfmt --to=si
quelle
Die bisher gegebenen Antworten berücksichtigen nicht, dass die von find an du übergebene Dateiliste so lang sein kann, dass find die Liste automatisch in Blöcke aufteilt, was zu mehreren Vorkommen von führt
total
.Sie können entweder
grep total
(Gebietsschema!) Und manuell zusammenfassen oder einen anderen Befehl verwenden. AFAIK: Es gibt nur zwei Möglichkeiten, eine Gesamtsumme (in Kilobyte) aller durch find gefundenen Dateien zu erhalten:find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'
Erläuterung
find . -type f -iname '*.jpg' -print0
: Suchen Sie alle Dateien mit der Erweiterung jpg, unabhängig von der Groß- und Kleinschreibung (z. B. * .jpg, * .JPG, * .Jpg ...), und geben Sie sie aus (nullterminiert).xargs -r0 du -a
: -r: Xargs würde den Befehl auch ohne Argumente aufrufen, was -r verhindert. -0 bedeutet nullterminierte Zeichenfolgen (nicht mit Zeilenvorschub abgeschlossen).awk '{sum+=$1} END {print sum}'
: Fassen Sie die vom vorherigen Befehl ausgegebenen Dateigrößen zusammenUnd als Referenz wäre der andere Weg
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-
quelle
du --file0-from
hat länger gedauert, weil du es zuerst ausgeführt hast (Caching-Effekt).xargs
können mehrere ausgeführtdu -a
werden, sodass es bei harten Links zu Unstimmigkeiten kommen kann.Wenn die Liste der Dateien zu groß ist, als dass sie
du -c
auf einem GNU-System an einen einzelnen Aufruf von nicht übergeben werden kann, haben Sie folgende Möglichkeiten :(Größe ausgedrückt in 512-Byte-Blöcken). Wie
du
es versucht, feste Verbindungen nur einmal zu zählen. Wenn Sie sich nicht für Hardlinks interessieren, können Sie es vereinfachen, um:Wenn Sie die Größe anstelle der Festplattenbelegung verwenden möchten, ersetzen Sie sie
%b
durch%s
. Die Größe wird dann in Bytes angegeben.quelle
-bash: bc: command not found
Centos - Linux 2.6.32-431.el6.x86_64bc
ist ein nicht optionaler POSIX-Befehl.Die bisher genannten Lösungen sind ineffizient (exec ist teuer) und erfordern zusätzliche manuelle Arbeit, wenn die Dateiliste lang ist oder sie unter Mac OS X nicht funktionieren. Die folgende Lösung ist sehr schnell und sollte auf jedem System funktionieren ergibt die Gesamtantwort in GB (entferne a / 1024, wenn du die Gesamtantwort in MB sehen willst):
find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'
quelle
-iname
noch-ls
sind Standard / tragbar, so dass es nicht auf jedem System arbeiten entweder. Es wird auch nicht richtig funktionieren, wenn es Dateinamen oder Symlink-Ziele gibt, die Zeilenumbrüche enthalten.Die großartige Antwort von SHW dahingehend verbessern, dass sie mit jedem Gebietsschema funktioniert, wie Zbyszek bereits in seinem Kommentar ausgeführt hat:
quelle
du durchquerst natürlich die Verzeichnishierarchie und awk kann die Filterung durchführen, so dass so etwas ausreichend sein kann:
Dies funktioniert ohne GNU.
quelle
stat
Dateien aufgerufen werden müssen, die nicht dem gesuchten Muster entsprechen.