Linux Shell: Anzahl Dateien und Speicherverbrauch pro Unterverzeichnis

Ein Shell-Einzeiler:

for i in */; do echo -ne "$i\tfiles: "; ls -A $i | wc -l | head -c -1 ; echo -ne "\t"; du -hs $i | cut -f1;  done

ergibt:

2014-06-12/     files: 15446    1,2G
2014-06-13/ files: 43188 3,3G
[...]

Der Reihe nach:

  1. */ lässt die Shell selbst auf alle Verzeichnisse im aktuellen Unterverzeichnis auflösen. Ausprobieren kann man das mit echo */. Durch das Verwenden genauerer Filter lässt sich nach speziellen Unterverzeichnissen filtern, z.B. 2014*/. (Wichtig ist für uns hier nur der "/" am Ende, damit wir nur Verzeichnisse bekommen.)
    Die for Schleife läuft für jeden so erhaltenen Wert (gespeichert als $i) durch.
  2. echo -ne erlaubt Steuersymbole (-e) wie "\t" für Tabulatoren und gibt keine abschließende Leerzeile aus (-n)
  3. ls -A $i listet alle Verzeichnisse und Dateien (auch versteckte Einträge, wie ".secret", aber nicht "." und ".." wie es "-a" tun würde). Hier könnte man die zu zählenden Dateien auch weiter filtern, z.B. mit ls -A $i./thumb-0000*jpg 2>/dev/null alle Dateien die dem gegebenen Muster entsprechen. Wichtig ist hier die Verwendung von "./" und Fehlermeldungen müssen ignoriert werden ("2>/dev/null"), sonst wird unsere Formatierung zerstört. Wenn auf diese Weise Dateien gefiltert werden, wird dieser Filter aber nicht für den Platzbedarf übernommen!
  4. wc -l zählt die Zeilen, also die von ls übergebenen Einträge
  5. head -c -1 entfernt das letzte Zeichen - das ist der Zeilenumbruch (damit bleiben wir in der selben Zeile!)
  6. echo -ne "\t" formatiert unsere Ausgabe (s.o.)
  7. du -hs $i errechnet den Platzverbrauch des Unterverzeichnisses.
    Um hier wie bei der Zählung der Dateien zu filtern muss folgendes statt dessen verwendet werden:
    ls -A $i./thumb-0000*jpg 2>/dev/null | tr \\n \\0 | du -hc --files0-from=- | tail -n1
    Der Output von ls (wie oben) wird mittr konvertiert (Zeilenumbrüche werden durch \0 ersetzt) und du angewiesen, die zu zählenden Argumente von StdIn zu lesen (--files0-from=-). du gibt jetzt für jede Datei ihre Größe an und Dank -c am Ende der einzelnen Ergebnisse eine totale Summe aus. Das ist das einzige, was uns interessiert, darum verwenden wir tail -n1 um diese letzte Zeile zu erhalten.
  8. cut -f1 gibt uns nur die erste Spalte der Ausgabe von du

Viel Spaß damit!