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?

user2566898
la source
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
Pavel Anossov
la source
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

EmptyData
la source
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

shiyani suresh
la source
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
Brainmaniac
la source
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é!

Manish Shrivastava
la source
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
textral
la source
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.

Briceburg
la source
Renvoie
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

MTK
la source
4

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

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

user1388547
la source
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.).

gniourf_gniourf
la source
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.

Anne van Rossum
la source
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"
Margenn
la source
0

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

ls -c | grep "^d" | wc -l
makassi
la source
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
Dr Personne Personne II
la source
-1

Meilleure façon de le faire:

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

Cela vous donne le décompte parfait.

Manoj
la source
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