Pour rechercher uniquement les répertoires feuilles contenant des fichiers, vous pouvez combiner une réponse à la question référencée https://unix.stackexchange.com/a/203991/330217 ou à des questions similaires https://stackoverflow.com/a/4269862/10622916 ou https://serverfault.com/a/530328 avec find
est ! -empty
find rootdir -type d -links 2 ! -empty
Vérification des liens durs avec -links 2
devrait fonctionner pour les systèmes de fichiers UNIX traditionnels. Le -empty
condition ne fait pas partie de la norme POSIX, mais devrait être disponible sur la plupart des systèmes Linux.
Selon le commentaire de KamilMaciorowski, la sémantique traditionnelle du nombre de liens pour les répertoires n'est pas valide pour Btrfs. Ceci est confirmé dans https://linux-btrfs.vger.kernel.narkive.com/oAoDX89D/btrfs-st-nlink-for-directories qui mentionne également Mac OS HFS+ comme une exception au comportement traditionnel. Pour ces systèmes de fichiers, une méthode différente est nécessaire pour vérifier les répertoires feuilles.
Vous pouvez utiliser find
imbriqué et compter le nombre de sous-répertoires :
find . -type d \
\( -exec sh -c 'find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | grep -cz "^" >/dev/null 2>&1' _ {} \; -o -print \)
Si le */
Le modèle de globalisation de nom de fichier se développe en quelque chose qui n'est pas le nom d'un répertoire, alors le répertoire actuel n'a pas de sous-répertoires (non cachés).
Avec find
:
find root -type d -exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; ! -empty -print
Notez que cela traiterait un lien symbolique vers un répertoire dans un répertoire feuille comme un répertoire puisque le modèle traverserait le lien symbolique.
Le -empty
Le prédicat n'est pas standard, mais souvent implémenté. Sans cela, vous feriez quelque chose de similaire à la détection des sous-répertoires :
find root -type d \
-exec sh -c 'set -- "$1"/*/; [ ! -d "$1" ]' sh {} \; \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print
Ou, un peu plus efficacement,
find root -type d -exec sh -c '
dir=$1
set -- "$dir"/*/
[ -d "$1" ] && exit 1
set -- "$dir"/*
[ -e "$1" ]' sh {} \; -print
Ou, en utilisant le -links
prédicat que j'avais oublié (merci Bodo):
find root -type d \
-links 2 \
-exec sh -c 'set -- "$1"/*; [ -e "$1" ]' sh {} \; -print