Kann ich die Anzahl der Unterverzeichnisse in einem Verzeichnis mit `ls -l` bestimmen?

8

Bei der Anzeige von Verzeichnissen mit ls -lbeträgt die Anzahl der Verknüpfungen (das zweite Feld in der Ausgabe) mindestens zwei: eine für den Verzeichnisnamen und eine für.

$ mkdir foo
$ ls -l
total 2
drwxr-xr-x  2 user   wheel  512  4 oct 14:02 foo

Ist es sicher anzunehmen, dass die Anzahl der Links über 2 der Anzahl der Unterverzeichnisse in diesem Verzeichnis ( ..Links) entspricht?

Eugene Yarmash
quelle

Antworten:

7

Auf Unix-Systemen ist es normalerweise so , dass die Anzahl der Links zu einem Verzeichnis der Anzahl der Unterverzeichnisse plus 2 entspricht. Es gibt jedoch Fälle, in denen dies nicht zutrifft:

  • Einige Unices erlauben feste Links zu Verzeichnissen. Dann gibt es mehr als 2 Links, die nicht den Unterverzeichnissen entsprechen.

  • Es gibt Dateisysteme, in denen Verzeichnisse keine Einträge für .und haben ... Das GNU-Suchhandbuch erwähnt einige Beispiele in der Diskussion seiner -noleafOption (die eine Optimierung deaktiviert, die dies voraussetzt .und ..in allen Verzeichnissen vorhanden ist): "CD-ROM- oder MS-DOS-Dateisysteme oder AFS-Volume-Mount-Punkte"

Eine fast zuverlässige Methode zum Zählen der Anzahl der Unterverzeichnisse (es kann immer noch fehlschlagen, wenn ein Dateiname ein Zeilenumbruchzeichen enthält) ist

$(($(LC_ALL=C ls -la /path/to/directory | grep '^d' | wc -l) - 2)

Ein zuverlässigerer Weg verwendet Shell Globs */und .*/; Wie üblich ist der Umgang mit dem Fall, in dem das Muster nicht übereinstimmt, etwas schmerzhaft (außer in Bash und Zsh, wo Sie die nullglobOption aktivieren können ).

Gilles 'SO - hör auf böse zu sein'
quelle
2

Hier ist noch eine andere Möglichkeit, Unterverzeichnisse (nicht rekursiv) in Bash zu zählen:

(
shopt -s nullglob dotglob
printf '%s\000' */ | tr -dc '\0' | wc -c  # wc counts null bytes
)

Da jeder Dateiname durch ein ASCII-NUL-Zeichen beendet wird, sollte dies auch dann ordnungsgemäß funktionieren, wenn ein Dateiname ein Zeilenumbruchzeichen enthält.

matt
quelle
2

Sie könnten versuchen mit:

ls -l |grep ^d | wc -l
HandyGandy
quelle
1

Ich kann in der Dokumentation nichts finden, was bestätigt, dass die Anzahl der Links immer +2 auf die Anzahl der Unterverzeichnisse beträgt.

Um den richtigen Betrag zu finden, verwenden Sie:

find . -type d -mindepth 1  -maxdepth 1 | wc -l

Oder wenn Sie verwenden müssen ls -l, sehen Sie die andere Antwort.

Stefan
quelle
Ich denke, Sie meinten -type d, aber: 1. dies erfordert GNU-Fund; 2. Sie müssen 1 für das Startverzeichnis (oder den Pass -mindepth 1) subtrahieren .
Gilles 'SO - hör auf böse zu sein'
0

Verwenden Sie nicht lsfür diese . Hier ist eine Möglichkeit, die mit allen Dateinamen funktioniert , auch mit solchen, die Zeilenumbrüche enthalten, da anstelle des Dateinamens nur ein Zeilenumbruchzeichen gedruckt wird:

find . -mindepth 1 -maxdepth 1 -type d -printf '\n' | wc -l

Bearbeiten: Die aktuelle Version führt zu keinen Warnungen, da -mindepthund -maxdepthsollte vorher sein -type(der Verzeichnisbaum wird vor dem Suchen nach Verzeichnissen gelöscht, um Zeit zu sparen).

l0b0
quelle