find . -type f | wc -l zählt alle Dateien unterhalb des aktuellen Verzeichnisses samt Unterordnern und lässt die Verzeichnisse selbst weg. Interessant sind meist die Aufschlüsselungen — nach Endung und nach Unterordner — und es gibt einen Fall, in dem wc -l lügt: ein Dateiname mit Zeilenumbruch.
1. Wie viele Dateien insgesamt
$ clai wie viele dateien liegen in diesem ordner und allen unterordnern→ find . -type f | wc -l20
-type f lässt Verzeichnisse und Symlinks weg, deshalb bedeutet die Zahl etwas. ls | wc -l antwortet im selben Ordner 3: es sieht nur die oberste Ebene und zählt Verzeichnisse als Einträge.
2. Aufschlüsselung nach Endung
$ clai zähle die dateien nach endung→ find . -type f -name '*.*' | sed 's/.*\.//' | sort | uniq -c | sort -rn 7 jpg 6 py 4 md 1 txt 1 png 1 bin
Das ist meist die Frage hinter der Frage: woraus besteht dieses Verzeichnis eigentlich. -name '*.*' lässt Dateien ohne Endung weg — sonst gibt sed deren kompletten Namen zurück.
3. Aufschlüsselung nach Unterordner
$ clai zähle die dateien in jedem unterordner→ for d in */; do printf '%5s %s\n' "$(find "$d" -type f | wc -l)" "$d"; done 3 docs/ 8 img/ 7 src/
Eine Schleife über die Verzeichnisse der obersten Ebene, in jedem rekursiv gezählt. Versteckte Verzeichnisse passen nicht auf */, deshalb ist die Summe kleiner als die Gesamtzahl.
4. Ohne versteckte Dateien
$ clai zähle die dateien ohne die versteckten→ find . -type f -not -path '*/.*' | wc -l18
20 gegen 18 — genau die beiden Punktdateien. -not -path '*/.*' schließt auch alles in versteckten Verzeichnissen wie .git aus, und meist war genau das gemeint.
5. Die Falle: Zeilenumbruch im Dateinamen
$ clai zähle dateien zuverlässig auch wenn namen zeilenumbrüche enthalten→ find . -type f -printf '.' | wc -c21
Geprüft an einer Datei, deren Name über zwei Zeilen geht: find . -type f | wc -l meldet im selben Verzeichnis 22. wc -l zählt Zeilen, nicht Dateien. -printf '.' gibt pro Datei einen Punkt aus, und die Zahl stimmt wieder. Portabel ohne GNU-Erweiterungen: find . -type f -print0 | tr -dc '\0' | wc -c.
6. Dateien und Verzeichnisse in einer Zeile
$ clai zeige wie viele dateien und wie viele verzeichnisse hier sind→ printf 'files: %s\ndirs: %s\n' "$(find . -type f | wc -l)" "$(find . -type d | wc -l)"
-type d zählt auch das aktuelle Verzeichnis mit, deshalb ist die Verzeichniszahl immer eins höher als erwartet.
Gotchas
ls | wc -lzählt das Falsche. Es geht nie in Unterordner, zählt dafür Verzeichnisse mit und überspringt Punktdateien. Die gestellte Frage beantwortetfind -type f.wc -lscheitert an Zeilenumbrüchen in Namen. Geprüft: 21 Dateien, Antwort 22. Kommt das Verzeichnis von außen — von Nutzern, aus einem Archiv, von einem Scraper —, zählen Sie mit-printf '.'oder-print0.find .läuft in versteckte Verzeichnisse. In einem Repository fügt allein.gitTausende Dateien hinzu. Mit-not -path '*/.*'filtern, sonst sagt die Zahl nichts aus.
Related questions
Wie zähle ich nur die oberste Ebene? find . -maxdepth 1 -type f | wc -l steigt nicht in Unterordner ab.
Wie zähle ich einen Dateityp? find . -type f -name '*.log' | wc -l. Groß- und Kleinschreibung zählt; mit -iname nicht.
Und wenn ich die Größe statt der Anzahl brauche? du -sh . gibt die Gesamtgröße, du -h --max-depth=1 | sort -h die Aufschlüsselung nach Unterordner.
See also
CliAI macht aus "wie viele Dateien nach Typ" die ganze Pipeline und zeigt sie vor dem Ausführen. In einer Zeile installieren.