Das scheint ziemlich gut zu funktionieren:
find . -type f -print0 | xargs -0 ls -l | awk '{size[int(log($5)/log(2))]++}END{for (i in size) printf("%10d %3d\n", 2^i, size[i])}' | sort -n
Seine Ausgabe sieht so aus:
0 1
8 3
16 2
32 2
64 6
128 9
256 9
512 6
1024 8
2048 7
4096 38
8192 16
16384 12
32768 7
65536 3
131072 3
262144 3
524288 6
2097152 2
4194304 1
33554432 1
134217728 4
wobei die Zahl auf der linken Seite die untere Grenze eines Bereichs von diesem Wert bis zum Doppelten dieses Werts ist und die Zahl auf der rechten Seite die Anzahl der Dateien in diesem Bereich ist.
Basierend auf der Antwort von garyjohn ist hier ein Einzeiler, der die Ausgabe auch für Menschen lesbar formatiert:
find . -type f -print0 | xargs -0 ls -l | awk '{ n=int(log($5)/log(2)); if (n<10) { n=10; } size[n]++ } END { for (i in size) printf("%d %d\n", 2^i, size[i]) }' | sort -n | awk 'function human(x) { x[1]/=1024; if (x[1]>=1024) { x[2]++; human(x) } } { a[1]=$1; a[2]=0; human(a); printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }'
Hier ist die erweiterte Version davon:
find . -type f -print0 \
| xargs -0 ls -l \
| awk '{ n=int(log($5)/log(2)); \
if (n<10) n=10; \
size[n]++ } \
END { for (i in size) printf("%d %d\n", 2^i, size[i]) }' \
| sort -n \
| awk 'function human(x) { x[1]/=1024; \
if (x[1]>=1024) { x[2]++; \
human(x) } } \
{ a[1]=$1; \
a[2]=0; \
human(a); \
printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }'
In der ersten awk
Ich habe eine Mindestdateigröße definiert, um alle Dateien mit weniger als 1 KB an einem Ort zu sammeln. Im zweiten awk
, Funktion human(x)
ist definiert, um eine vom Menschen lesbare Größe zu erstellen. Dieser Teil basiert auf einer der Antworten hier:https://unix.stackexchange.com/questions/44040/a-standard-tool-to-convert-a-byte-count-into-human-kib-mib-etc -wie-du-ls1
Die Beispielausgabe sieht folgendermaßen aus:
1k: 335
2k: 16
32k: 5
128k: 22
1M: 54
2M: 11
4M: 13
8M: 3
Versuchen Sie Folgendes:
find . -type f -exec ls -lh {} \; |
gawk '{match($5,/([0-9.]+)([A-Z]+)/,k); if(!k[2]){print "1K"} \
else{printf "%.0f%s\n",k[1],k[2]}}' |
sort | uniq -c | sort -hk 2
AUSGABE :
38 1K
14 2K
1 30K
2 62K
12 2M
2 3M
1 31M
1 46M
1 56M
1 75M
1 143M
1 191M
1 246M
1 7G
ERKLÄRUNG :
-
find . -type f -exec ls -lh {} \;
:Einfach genug, finde Dateien im aktuellen Verzeichnis und führels -lh
aus auf ihnen -
match($5,/([0-9.]+)([A-Z]+)/,k);
:Dadurch wird die Dateigröße extrahiert und jede Übereinstimmung im Arrayk
gespeichert . -
if(!k[2]){print "1K"}
:wennk[2]
undefiniert ist, ist die Dateigröße <1K. Da ich mir vorstelle, dass Ihnen solche winzigen Größen egal sind, gibt das Skript1K
aus für alle Dateien, deren Größe <=1K ist. -
else{printf "%.0f%s\n",k[1],k[2]}
:Wenn die Datei größer als 1 KB ist, runden Sie die Dateigröße auf die nächste ganze Zahl und drucken Sie sie zusammen mit ihrem Modifikator (K, M oder G). -
sort | uniq -c
:Zählt das Vorkommen jeder gedruckten Zeile (Dateigröße). -
sort -hk 2
:Sortieren nach dem zweiten Feld in menschenlesbarem Format. Hier entlang,7G
wird nach8M
sortiert .