compter le nombre de répertoires dans un répertoire spécifique


103

Comment compter le nombre de dossiers dans un répertoire spécifique. J'utilise la commande suivante, mais elle en fournit toujours une supplémentaire.

find /directory/ -maxdepth 1 -type d -print| wc -l

Par exemple, si j'ai 3 dossiers, cette commande en fournit 4. Si elle contient 5 dossiers, la commande en fournit 6. Pourquoi?


4
Le nombre supplémentaire de 1 est là en raison du répertoire courant '.' , qui est également pris en compte par «find».
patel deven

Réponses:


94

find imprime également le répertoire lui-même:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

Vous pouvez à la place tester les enfants du répertoire et ne pas y descendre du tout:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

Vous pouvez également utiliser ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

Agréable! Comment feriez-vous cela $ ls -l .vimavec PHP? Ou comment obtenir uniquement le total, sans la liste. Je veux dire, dans ce cas, obtenez seulement 52?
Pathros

Hah. J'aime la façon dont l'argument contre PowerShell est que BASH est plus facile à tous points de vue ... voulez voir la commande POSH pour faire cela? (ls).Count
Kolob Canyon

@Pathros Utilisez glob avec l'indicateur GLOB_ONLYDIR et count () le résultat.
Pilipe

1
ls -l | grep -c ^dest très simple et fonctionne. @Pathros il existe probablement un meilleur moyen en PHP, mais dans le pire des cas en PHP, vous pouvez toujours utiliser la fonction shell_exec () pour exécuter la ligne de commande et renvoyer les résultats dans une chaîne. ie $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte

66

Obtenez un décompte uniquement des répertoires du répertoire actuel

echo */ | wc

vous sortirez comme 1 309 4594

2nd digitreprésente non. d'annuaires.

ou

tree -L 1 | tail -1


8
Cela échoue s'il y a des espaces dans les noms de répertoire, malheureusement.
Michael Campbell

zsh: no matches found: */besoins nullglob
Anne van Rossum

@AnnevanRossum Avez-vous echo. typewhich echo
EmptyData

7
Le premier peut être encore amélioré un peu:echo */ | wc -w
ibic

Nota que cela comptera 1 s'il n'y a pas de répertoires au lieu de 0.
jinawee

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

Car trouver -mindepthsignifie le nombre total de récusations dans les répertoires

-maxdepth signifie nombre total de récusations dans les répertoires

-type d signifie répertoire

Et pour des wc -lmoyens compter les lignes de l'entrée


2
Pouvez-vous expliquer votre réponse s'il vous plaît (dans votre réponse)?
Zulu

-mindepth signifie le nombre total de récusations dans les répertoires, -maxdepth signifie le nombre total de récusations dans les répertoires, -type d signifie le répertoire et wc -l signifie le nombre de lignes de la liste de répertoires donnée
shiyani suresh

find . -mindepth 1 -maxdepth 1 -type d | wc -lvous donnera beaucoup d'espaces entre le nombre, par exemple: `2` vous pouvez l'empêcher en utilisant ceci: dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 et pourrait être utile pour des conditions, comme:if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
naorz

16

Si vous n'avez que des répertoires dans le dossier et aucun fichier, procédez comme suit:

ls | wc -l

2
Cela obtient également des fichiers, mais la question concernait les dossiers / répertoires.
Robert

12

Meilleur moyen de naviguer vers votre lecteur et d'exécuter simplement

ls -lR | grep ^d | wc -l

et pour trouver tous les dossiers au total, y compris les sous-répertoires?

find /mount/point -type d | wc -l

... ou trouver tous les dossiers dans le répertoire racine (sans compter les sous-répertoires)?

find /mount/point -maxdepth 1 -type d | wc -l

À votre santé!


Notez que les ls précédents -lRignorent le répertoire avec le préfixe de points tout en les find -type d comptant. Ainsi, le décompte donné par la première commande est faux si vous avez des répertoires avec le préfixe de points (par exemple, vous avez un sous-répertoire .git!). Vous ne pouvez pas simplement utiliser -lRacar vous obtenez également pour chaque répertoire un .et une ..entrée. Cela s'applique également à la réponse de @Pavel Anossov
marcz

12

Exécutez stat -c %h folderet soustrayez 2 du résultat. Cela n'emploie qu'un seul sous-processus par opposition aux 2 (ou même 3) requis par la plupart des autres solutions ici (généralement findplus wc).

Utilisation de sh / bash:

cnt = $ ((`stat -c% h dossier` - 2))
echo $ cnt # 'echo' est un sh / bash intégré, pas un processus supplémentaire

En utilisant csh / tcsh:

@ cnt = `stat -c% h dossier` - 2
echo $ cnt # 'echo' est un csh / tcsh intégré, pas un processus supplémentaire


Explication: stat -c %h folderimprime le nombre de liens physiques vers le dossier , et chaque sous- dossier sous dossier contient une entrée ../ qui est un lien direct vers le dossier . Vous devez soustraire 2 car il y a deux liens physiques supplémentaires dans le décompte:

  1. la propre entrée ./ auto-référentielle du dossier , et
  2. dossier lien de parent de » au dossier

Lié à cette question: [Pourquoi un nouveau répertoire a-t-il un nombre de liens durs de 2 avant que quoi que ce soit ne soit ajouté? ] ( unix.stackexchange.com/questions/101515 ) Cela explique pourquoi c'est une excellente réponse. Malheureusement, cela n'a pas reçu suffisamment d'attention! Bien que ce soit une bonne réponse, le résultat dépend malheureusement du système de fichiers, mais pour la plupart des systèmes de fichiers courants, cela fonctionnera.
kvantour

8

Je pense que le plus simple est

  ls -ld images/* | wc -l

imagesest votre répertoire cible. L'indicateur -d limite les répertoires, et l'indicateur -l effectuera une liste par ligne, compatible avec le très familier wc -lpour le nombre de lignes.



1
Selon man ls, -ddoes: "lister les répertoires eux-mêmes, pas leur contenu", c'est-à-dire que si vous exécutez ls /tmp, vous obtiendrez ce qu'il y a /tmp, et si vous exécutez, ls -d /tmpvous obtenez simplement /tmp. Le -dcommutateur ne filtre pas les répertoires, comme cela a été demandé.
Robert

5

Quelques exemples utiles:

compter les fichiers dans le répertoire actuel

/bin/ls -lA  | egrep -c '^-'

compter les répertoires dans le répertoire courant

/bin/ls -lA  | egrep -c '^d'

compter les fichiers et les répertoires dans le répertoire actuel

/bin/ls -lA  | egrep -c '^-|^d'

compter les fichiers et les répertoires dans un sous-répertoire

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

J'ai remarqué une chose étrange (du moins dans mon cas):

Quand j'ai essayé avec à la lsplace /bin/ls le -Aparamètre do not list implied . and ..NE FONCTIONNE PAS comme prévu. Quand j'utilise lsce spectacle ./ et ../ Donc, ce résultat ne compte pas. SOLUTION: à la /bin/lsplacels


4

Aucun répertoire que nous pouvons trouver en utilisant la commande ci-dessous

ls -l | grep "^d" | wc -l


Je ls -l | grep ^d | wc -lvais le faire, il n'est pas nécessaire d'utiliser "ici
kaspiotr

3

Une solution pure bash:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Si vous souhaitez également compter les répertoires cachés:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Notez que cela comptera également les liens vers les répertoires. Si vous ne le souhaitez pas, c'est un peu plus difficile avec cette méthode.


Utilisation find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

L'astuce consiste à afficher un xvers stdout chaque fois qu'un répertoire est trouvé, puis à l'utiliser wcpour compter le nombre de caractères. Cela comptera le nombre de tous les répertoires (y compris ceux cachés), à l'exclusion des liens.


Les méthodes présentées ici sont toutes sans danger pour les caractères amusants qui peuvent apparaître dans les noms de fichiers (espaces, retours à la ligne, caractères globaux, etc.).


C'est la meilleure solution présentée dans cette question et fonctionnera toujours!
kvantour

3

Utilisation zsh:

a=(*(/N)); echo ${#a}

Le Nest un nullglob, le /fait correspondre aux répertoires, #compte. Il gérera parfaitement les espaces dans les noms de répertoire ainsi que les retours 0s'il n'y a pas de répertoires.


0

Comptez tous les fichiers et sous-dossiers, style Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"

0

Si vous souhaitez utiliser des expressions régulières, essayez:

ls -c | grep "^d" | wc -l

1
Souhaitez-vous ajouter des explications à votre réponse en code uniquement? Cela aiderait à combattre l'idée fausse selon laquelle StackOverflow est un service d'écriture de code gratuit. Jetez également un œil ici pour améliorer l'apparence: stackoverflow.com/editing-help
Yunnosch

0

La meilleure réponse à ce que vous voulez est

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

cela en soustrait un pour supprimer le «.» indésirable. répertoire qui trouve des listes (comme patel deven mentionné ci-dessus).

Si vous voulez compter les sous-dossiers de manière récursive, laissez simplement l'option maxdepth, donc

echo `find . -type d | wc -l`-1 | bc

PS Si vous trouvez la substitution de commande moche, en soustraire une peut être faite comme un flux pur en utilisant sedet bc.

Soustraire un du nombre:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

ou, en ajoutant le nombre à moins un:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc

-1

Meilleure façon de le faire:

ls -la | grep -v total | wc -l

Cela vous donne le décompte parfait.


6
Vous voulez dire que c'est la pire façon de le faire! de plus, cela ne compte pas le nombre de répertoires. Et si un nom de répertoire contient la chaîne total? votre méthode est cassée :(. N'analyse pasls !
gniourf_gniourf
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.