web-dev-qa-db-fra.com

Comment compter tous les fichiers récursivement dans les répertoires

Je veux voir combien de fichiers se trouvent dans les sous-répertoires pour savoir où se trouve toute l'utilisation des inodes sur le système. Un peu comme je le ferais pour l'utilisation de l'espace

du -sh /*

ce qui me donnera l'espace utilisé dans les répertoires hors root, mais dans ce cas je veux le nombre de fichiers, pas la taille.

52
xenoterracide
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Merci à Gilles et xenoterracide pour les correctifs de sécurité/compatibilité.

La première partie: find -maxdepth 1 -type d renverra une liste de tous les répertoires du répertoire de travail actuel. C'est canalisé pour ...

La seconde partie: while read -r dir; do commence une boucle while - tant que le canal entrant dans le while est ouvert (c'est-à-dire jusqu'à l'envoi de la liste complète des répertoires), la commande read place la ligne suivante dans la variable "dir". Puis ça continue ...

La troisième partie: printf "%s:\t" "$dir"; affichera la chaîne dans "$ dir" (qui contient l'un des noms de répertoire) suivie d'un onglet.

La quatrième partie: find "$dir -f file" fait une liste de tous les fichiers dans le nom du répertoire contenu dans "$ dir". Cette liste est envoyée à ..

La cinquième partie: wc -l; compte le nombre de lignes envoyées dans son entrée standard.

La dernière partie: done termine simplement la boucle while.

Nous obtenons donc une liste de tous les répertoires du répertoire courant. Pour chacun de ces répertoires, nous générons une liste de tous les fichiers qu'il contient afin de pouvoir tous les compter en utilisant wc -l. Le résultat ressemblera à:

./dir1: 234
./dir2: 11
./dir3: 2199
...
67
Shawn J. Goff

Essayez find . -type f | wc -l, il comptera tous les fichiers du répertoire courant ainsi que tous les fichiers des sous-répertoires. Notez que tous les répertoires ne seront pas comptés comme des fichiers, seuls les fichiers ordinaires le font.

17
herohuyongtao

Voici une compilation de quelques commandes de listage utiles (ré-hachées basées sur le code des utilisateurs précédents):

Liste des dossiers avec le nombre de fichiers:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Liste des dossiers avec un nombre de fichiers différent de zéro:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liste des dossiers avec le nombre de sous-dossiers:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Liste des dossiers avec un nombre de sous-dossiers différent de zéro:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liste des dossiers vides:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liste des dossiers non vides avec le nombre de contenus:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
13
DolphinDream

Essayer:

find /path/to/start/at -type f -print | wc -l

comme point de départ, ou si vous ne voulez vraiment parcourir que les sous-répertoires d'un répertoire (et ignorer les fichiers de ce répertoire de niveau supérieur)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
12
Cry Havok

La solution suivante compte le nombre réel d'inodes utilisés à partir du répertoire actuel:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Pour obtenir le nombre de fichiers du même sous-ensemble, utilisez:

find . | wc -l

Pour les solutions explorant uniquement les sous-répertoires, sans prendre en compte les fichiers du répertoire courant, vous pouvez vous référer à d'autres réponses.

4
mouviciel

OS X 10.6 s'étouffe avec la commande dans la réponse acceptée, car elle ne spécifie pas de chemin pour find. Utilisez plutôt:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
2
abeboparebop

Je sais que je suis en retard à la fête, mais je crois que cette solution pure bash (ou autre Shell qui accepte les globes à double étoile) pourrait être beaucoup plus rapide dans certaines situations:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

production:

d1/:    302
d2/:    24
d3/:    640
...
2
jimmij

Essayez ceci:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Cela devrait fonctionner correctement, sauf si les noms de fichiers incluent des retours à la ligne.

du --inodes

Je ne sais pas pourquoi personne (moi y compris) n'était au courant de:

du --inodes
--inodes
      list inode usage information instead of block usage

Je suis presque sûr que cela résout le problème de l'OP. J'ai commencé à l'utiliser beaucoup pour découvrir où se trouvent toutes les ordures dans mes énormes disques (et les décharger sur un disque plus ancien).

Plus d'infos

Si vous NE VOULEZ PAS rechuter (ce qui peut être utile dans d'autres situations), ajoutez

-S, --separate-dirs
1
Sridhar Sarnobat

Si vous avez le ncdu installé (un indispensable lorsque vous voulez faire un peu de nettoyage), tapez simplement c pour "Basculer l'affichage du nombre d'éléments enfants". Et C à "Trier par éléments".

1
Demi-Lune