ich suche einen effizienten Weg, den Speicherplatz, den
bestimmte Dateitypen in einem Verzeichnisbaum belegen,
zu ermitteln, sinngemäß z.B.
find dir/ -name "*.log" | sumFileSizes
Im Grunde wäre das so, als würde man die erste Spalte
der Ausgabe von
ls -1Ssh (/bin/ls = GNU coreutils 6.9)
summieren - "human readable" Form ist also auch gewünscht.
Kann mir jemand weiterhelfen?
Danke vorab, Grüße,
Frank
> ich suche einen effizienten Weg, den Speicherplatz, den
> bestimmte Dateitypen in einem Verzeichnisbaum belegen,
> zu ermitteln, sinngemäß z.B.
>
> find dir/ -name "*.log" | sumFileSizes
So?
find . -printf '%k\n' | (while read i; do : $((sum += i)); done; echo $sum)
%b und %s (und vielleicht noch andere) kämen für find auch noch in
Frage.
> find dir/ -name "*.log" | sumFileSizes
> Kann mir jemand weiterhelfen?
Erster Schritt:
find ./tmp -iname "*jpg*" -printf %s\\n |
(sum=0;while read size; do sum=$((sum+size));done; echo $sum)
Zweiter Schritt:
echo 1234567890123456 | (read number; base=1024;
if [ $number -ge $base ]; then number=$((number/base)); unit=K;
if [ $number -ge $base ]; then number=$((number/base)); unit=M;
if [ $number -ge $base ]; then number=$((number/base)); unit=G;
if [ $number -ge $base ]; then number=$((number/base)); unit=T;
fi;fi;fi;fi; printf "%3.2f %s\n" $number $unit)
1122,00 T
CU
Hauke
--
http://www.hauke-laging.de/ideen/
Wie können 59.054.087 Leute nur so dumm sein?
Sowas z.B.?
du -sch *.jpg
Ciao Nobbe
Wäre schick, ist aber nicht zielführend, weil die Dateien,
wie erwähnt, über einen Verzeichnisbaum verstreut sind. Um
bei deinem Beispiel zu bleiben, würde ich gerne wissen wollen,
wie groß der insgesamt belegte Speicherplatz aller *.jpg
Dateien im angegebenen Verzeichnisbaum ist und
find . -name "*.jpg" | du -sch
geht leider nicht ....
Hoppala! Aber
find dir/ -name "*.log" | xargs du -sch
scheint zu gehen - sofern das Ergebnis stimmt.
Danke,
Frank
Okay, dann noch die Summe filtern, damit's passt:
find dir/ -name "*.log" | xargs du -sch | grep insgesamt
Scheint's zu tun :)
Klingt wie ein typischer Fall für AWK:
find -printf '%s\n' -name "*.log" | awk '{SUM+=$1} END{print SUM/1024 " kb"}'
find ermittelt die Größen der gefundenen Dateien, awk summiert auf.
--
ste...@pico.ruhr.de
GPG available and welcome
http://stefans.datenbruch.de/
> Okay, dann noch die Summe filtern, damit's passt:
>
> find dir/ -name "*.log" | xargs du -sch | grep insgesamt
>
> Scheint's zu tun :)
Aber wohl nur so lange, bis die Kommandozeilenlänge überschritten
wird und xargs weitere du startet.
Stimmt. Hab's gerade mit 1613 Dateien, die zu finden waren,
getestet. Ich bekam zweimal "insgesamt". Schade, wäre zu
schön gewesen: Kurz, knapp, überschaubar und mit Summenbildung.
Gibt es eine ähnlich kompakte Alternative?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Das liefert ein wesentlich anderes Ergebnis als:
find . -iname "*.log" -printf '%k\n'
Die Reihenfolge ist also relevant, warum, weiß ich nicht.
Gruß,
Frank
# Heike
find . -iname "*.tif" -printf '%k\n' | (while read i; do : $((sum += i)); done; echo $sum)
==> 64941368
# Hauke
find . -iname "*.tif" -printf %s\\n | (sum=0;while read size; do sum=$((sum+size));done; echo $sum)
==> 66421441940 (Bytes!)
# Stefan (Fehler "-printf ... -name" korrigiert)
find . -iname "*.tif" -printf '%k\n' | awk '{SUM+=$1} END{print SUM}'
==> 64941368
sind im Resultat gleich, jedoch liefert keiner dieser Vorschläge
eine "human" lesbare Version der Summe.
# Norbert (um "find ... | xargs" erweitert)
find . -iname "*.tif" | xargs du -sch
funktioniert nur, solange die durch "find" erzeugte Kommandozeile
nicht zu lang wird. Das führte bei mir zu zwei Teilsummen, statt
einer Gesamtsumme. Ansonsten sehr schick und kompakt.
Hauke schlug für die lesbare Summenformatierung sinngemäß vor:
find . -iname "*.tif" -printf %s\\n |
(sum=0;while read size; do sum=$((sum+size));done; echo $sum) |
(read number; base=1024; \
if [ $number -ge $base ]; then number=$((number/base)); unit=K; \
if [ $number -ge $base ]; then number=$((number/base)); unit=M; \
if [ $number -ge $base ]; then number=$((number/base)); unit=G; \
if [ $number -ge $base ]; then number=$((number/base)); unit=T; \
fi;fi;fi;fi; printf "%3.2f %s\n" $number $unit)
==> 61,00 G
Das funktioniert, allerdings hätte ich erwartet, dass es eine
kompaktere Formatiermöglichkeit gibt. Ich habe mir daraufhin
printf (1) und bc (1) angeschaut, aber keine passende Angabe
gefunden. Meine Frage also:
Gibt es einen Shell-Formatierer, der eine solche Zahl
als Bytes, KB, MB, GB, TB ausgeben kann?
"du", "ls" und sicher noch andere können's ja ....
Frank
Äh, das stimmt natürlich: Die Anweisung (printf) muss natürlich nach
dem Folterkommando (name/iname) stehen:
find . -name '*.log' -printf '%s\n' | awk '{SUM+=$1} END{print SUM/1024 " kb"}'
Da ist wohl beim stückchenweisen kopieren aus dem benachbarten Terminal
etwas kaputtgegangen.
> Gibt es einen Shell-Formatierer, der eine solche Zahl
> als Bytes, KB, MB, GB, TB ausgeben kann?
>
> "du", "ls" und sicher noch andere können's ja ....
Das sind aber alles keine Skripte.
kMG(){
read n
set 1000 k $((10**6)) M $((10**9)) G $((10**12)) T
while [ $((n/$1)) -gt 999 ]; do shift 2; done
echo "scale=3; print $n/$1, \" $2\n\"" | bc
}
hcz@minni:~$ echo 11234 | kMG
11.234 k
hcz@minni:~$ echo 1123456789 | kMG
1.123 G
hcz@minni:~$ echo 1 | kMG
.001 k
Anpassungen und Erweiterung des Zahlenbereichs in beide Richtungen sind
einfach und seien Dir überlassen.
| sfroehli@sokrates:~$ du -sh .
| 63G .
| sfroehli@sokrates:~$ find . -print0 |du -sch --files0-from=- |grep total
| 244G total
240G passen nicht einmal auf die Platte. Ich muss mir das noch einmal
genauer ansehen, vermutlich werden da irgendwelche symbolischen Links
mitgezaehlt.
Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Unverzichtbar - schmusen mit Stefan!
(Sloganizer)
> 240G passen nicht einmal auf die Platte. Ich muss mir das noch einmal
> genauer ansehen, vermutlich werden da irgendwelche symbolischen Links
> mitgezaehlt.
Dann halt so:
find . -name '*.log' -type f -printf '%s\n' | awk '{SUM+=$1} END{print SUM/1024 " kiB"}'
Ein Zusatz, den ich zu Unrecht aus dem Original fürs Posting
herausgekürzt habe:
> kMG(){
> read n
> set 1000 k $((10**6)) M $((10**9)) G $((10**12)) T
> while [ $((n/$1)) -gt 999 ]; do shift 2; done
while [ "$2" ] && [ $(($n/$1)) -gt 999 ]; do shift 2; done
> echo "scale=3; print $n/$1, \" $2\n\"" | bc
> }
Dann hast Du keine durchs Script bedingte Obergrenze.
> > | sfroehli@sokrates:~$ du -sh .
> > | 63G .
> >
> > | sfroehli@sokrates:~$ find . -print0 |du -sch --files0-from=- |grep total
> > | 244G total
> Mit der genannten Kommandozeile zählst Du auch insbesondere Links und
> andere Files als Logfiles mit!
Ich hatte gerade nicht mehr Zeit, als den (durchaus interessant
klingenden) Vorschlag kurz auszuprobieren. Dankenswerterweise hat
Du mir ja nun meine Vermutung bestaetigt. Wobei, viel schlimmer noch,
Verzeichnisse einmal komplett mitgezaehlt wurden, und ein weiteres Mal
alle darin enthaltenen Dateien. Mit 'find . -name "*.jpg"' ist das zwar
weniger wahrscheinlich, aber keineswegs unmoeglich - die Angabe von
"-type f" ist also unumgaenglich.
Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Das Jahr des frigiden Erfolgs von Stefan heißt: 2008.
(Sloganizer)