Puis-je déterminer le nombre de sous-répertoires dans un répertoire en utilisant `ls -l`?

8

Lors de l'affichage des répertoires à l'aide de ls -l, leur nombre de liens (le deuxième champ dans la sortie) est d'au moins deux: un pour le nom du dir et un pour.

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

Peut-on toujours supposer que le nombre de liens au-dessus de 2 correspond au nombre de sous-répertoires dans ce répertoire ( ..liens)?

Eugene Yarmash
la source

Réponses:

7

Il est généralement vrai sur les systèmes Unix que le nombre de liens vers un répertoire est le nombre de sous-répertoires plus 2. Cependant, il y a des cas où ce n'est pas vrai:

  • Certains unités autorisent les liens durs vers les répertoires. Ensuite, il y aura plus de 2 liens qui ne correspondent pas à des sous-répertoires.

  • Il existe des systèmes de fichiers où les répertoires n'ont pas d'entrées pour .et ... Le manuel GNU find mentionne quelques exemples dans la discussion de son -noleafoption (qui désactive une optimisation qui suppose cela .et qui ..existe dans tous les répertoires): «Systèmes de fichiers CD-ROM ou MS-DOS ou points de montage de volume AFS»

Un moyen presque fiable de compter le nombre de sous-répertoires (il peut toujours échouer si un nom de fichier contient un caractère de nouvelle ligne) est

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

Un moyen plus fiable utilise des globes shell */et .*/; comme d'habitude, gérer le cas où le motif ne correspond pas est un peu pénible (sauf en bash et zsh où vous pouvez activer l' nullgloboption).

Gilles 'SO- arrête d'être méchant'
la source
2

Voici encore une autre façon de compter les sous-répertoires (de manière non récursive) dans Bash:

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

Étant donné que chaque nom de fichier se termine par un caractère ASCII NUL, cela devrait fonctionner correctement même si un nom de fichier contient un caractère de nouvelle ligne.

mat
la source
2

Vous pouvez essayer avec:

ls -l |grep ^d | wc -l
HandyGandy
la source
1

Je ne trouve rien dans la documentation qui confirme que le nombre de liens sera toujours +2 sur le nombre de sous-répertoires.

Mais, pour trouver le montant correct, utilisez:

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

Ou si vous devez utiliser ls -l, voir l'autre réponse.

Stefan
la source
Je pense que vous vouliez dire -type d, mais: 1. cela nécessite GNU find; 2. vous devez soustraire 1 pour le répertoire de départ (ou passer -mindepth 1).
Gilles 'SO- arrête d'être méchant'
0

Ne l'utilisez pas lspour cela . Voici une méthode qui fonctionne avec tous les noms de fichiers, même ceux contenant des retours à la ligne, car elle imprime uniquement un caractère de nouvelle ligne au lieu du nom de fichier:

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

Edit: La version actuelle n'entraîne aucun avertissement, car -mindepthet -maxdepthdevrait être antérieure -type(l'arborescence des répertoires est élaguée avant de rechercher des répertoires, pour gagner du temps).

l0b0
la source