Um nur die Blattverzeichnisse zu finden, die Dateien enthalten, können Sie eine Antwort der referenzierten Frage https://unix.stackexchange.com/a/203991/330217 oder ähnliche Fragen https://stackoverflow.com/a/4269862/10622916 kombinieren oder https://serverfault.com/a/530328 mit find
ist ! -empty
find rootdir -type d -links 2 ! -empty
Überprüfung der Hardlinks mit -links 2
sollte für herkömmliche UNIX-Dateisysteme funktionieren. Die -empty
condition ist nicht Teil des POSIX-Standards, sollte aber auf den meisten Linux-Systemen verfügbar sein.
Laut KamilMaciorowskis Kommentar gilt die traditionelle Link-Count-Semantik für Verzeichnisse nicht für Btrfs. Dies wird in https://linux-btrfs.vger.kernel.narkive.com/oAoDX89D/btrfs-st-nlink-for-directories bestätigt, wo auch Mac OS HFS+ als Ausnahme vom traditionellen Verhalten erwähnt wird. Für diese Dateisysteme ist eine andere Methode erforderlich, um nach Blattverzeichnissen zu suchen.
Sie könnten verschachteltes find
verwenden und Anzahl der Unterverzeichnisse zählen:
find . -type d \
\( -exec sh -c 'find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | grep -cz "^" >/dev/null 2>&1' _ {} \; -o -print \)
Wenn der */
Wenn das Globbing-Muster für Dateinamen zu etwas erweitert wird, das nicht der Name eines Verzeichnisses ist, hat das aktuelle Verzeichnis keine (nicht versteckten) Unterverzeichnisse.
Mit find
:
find root -type d -exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; ! -empty -print
Beachten Sie, dass dies einen symbolischen Link zu einem Verzeichnis in einem Blattverzeichnis als Verzeichnis behandeln würde, da das Muster den symbolischen Link durchlaufen würde.
Die -empty
Prädikat ist kein Standard, aber oft implementiert. Ohne sie würden Sie etwas Ähnliches tun wie mit der Erkennung von Unterverzeichnissen:
find root -type d \
-exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print
Oder, etwas effizienter,
find root -type d -exec sh -c '
dir=$1
set -- "$dir"/*/
[ -d "$1" ] && exit 1
set -- "$dir"/*
[ -e "$1" ]' sh {} \; -print
Oder verwenden Sie den -links
Prädikat, das ich vergessen hatte (danke Bodo):
find root -type d \
-links 2 \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print