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

48

Je veux voir combien de fichiers sont dans les sous-répertoires pour savoir où tout l'utilisation d'inode est 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 en dehors de root, mais dans ce cas, je veux le nombre de fichiers, pas la taille.

xénoterracide
la source
Je pense que "combien de fichiers sont dans des sous-répertoires dans ces sous-répertoires" est une construction déroutante. Si vous énoncez plus clairement ce que vous voulez, vous obtiendrez peut-être une réponse qui correspond à la facture.
Steven D
@Steven n’hésitez pas à le réécrire ... j’ai pensé que mon exemple montrait du -sh /*clairement comment je voulais que le décompte fonctionne. Même chose, il suffit de compter les fichiers et non les octets.
xenoterracide
Comme vous avez mentionné l’utilisation d’inodes, je ne comprends pas si vous voulez compter le nombre de fichiers ou le nombre d’inodes utilisés. Les deux sont différents lorsque des liens physiques sont présents dans le système de fichiers. La plupart des réponses, sinon toutes, donnent le nombre de fichiers. Ne les utilisez pas sur un disque de sauvegarde Apple Time Machine.
mouviciel
@mouviciel ceci n'est pas utilisé sur un disque de sauvegarde, et oui je suppose qu'ils pourraient être différents, mais dans l'environnement dans lequel je suis situé, il y a très peu de liens en dur, techniquement, je dois juste en avoir une idée. déterminer où quelqu'un brûle son quota d'inode.
xenoterracide

Réponses:

61
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 dretournera une liste de tous les répertoires du répertoire de travail actuel. Ceci est canalisé à ...

La deuxième partie: while read -r dir; docommence une boucle while - tant que le tube entrant est ouvert (c'est-à-dire jusqu'à ce que la liste complète des répertoires soit envoyée), la commande read placera 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épertoires) suivie d'un onglet.

La quatrième partie: find "$dir -f file"dresse la liste de tous les fichiers du nom du répertoire 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: donetermine simplement la boucle while.

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

./dir1: 234
./dir2: 11
./dir3: 2199
...
Shawn J. Goff
la source
Utilisez toujours read -rcomme readtraitement ordinaire les antislashs. Ensuite echo -en "$dir:\t", supprimez de nouveau les barres obliques inverses; une solution simple consiste à utiliser à la printf '%s:\t' "$dir"place. Ensuite, $dirdevrait être "$dir"( utilisez toujours des guillemets doubles autour des substitutions de variables ).
Gilles, arrête de faire le mal '18
suggestions modifiées par @Gilesfind -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done
xenoterracide
2
J'ajoute sort -n -r -k2à la fin de ceci, pour beaucoup de répertoires, pour que je sache où est la plus grande utilisation
xenoterracide
La quatrième partie: trouver "$ dir" dresse la liste de tous les fichiers du nom du répertoire contenu dans "$ dir". Vous avez oublié d'ajouter -type fà faire la liste des fichiers:find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Krzysztof Boduch
1
Je ne veux pas que cela fonctionne sur macOS Sierra 10.12.5. illegal option -- mdans la findcommande. Je l'ai changé find . -maxdepth ...et je l'ai fait fonctionner.
Jeff
15

Essayez find . -type f | wc -l, il comptera tous les fichiers du répertoire actuel 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 seront.

Herohuyongtao
la source
13

Voici une compilation de commandes de listage utiles (recalées en fonction du code des utilisateurs précédents):

Liste des dossiers avec 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 non nul:

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 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 non nul:

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

Répertoriez les dossiers non vides avec le contenu:

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
DolphinDream
la source
Et d'ailleurs ... si vous souhaitez que la sortie de l'une de ces commandes de liste soit triée par le nombre d'éléments ... transformez la commande en un tri: "a-list-command" | sort -n
DolphinDream
12

Essayer:

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

comme point de départ, ou si vous ne voulez vraiment que lire à travers 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
Cry Havok
la source
+1 pour quelque chose | wc -l ... le nombre de mots est un si bel outil
Johan
oui, mais cela ne concerne qu'un répertoire ... J'aimerais obtenir le nombre de tous les répertoires d'un répertoire, et je ne veux pas l'exécuter séparément à chaque fois ... bien sûr, je suppose que je pourrais utiliser une boucle ... mais je suis paresseux.
xenoterracide
findfonctionne de manière récursive à travers tous les sous-répertoires par défaut. Si vous souhaitez qu'il fonctionne dans plusieurs emplacements, vous pouvez tous les spécifier entre findet -type.
Didier Trosset
ce deuxième ne fonctionne certainement pas ... Je l'ai essayé / à la maison. Je suis arrivé 698035 . Je devrais voir environ 6 chiffres.
xenoterracide
Cela fonctionne pour moi - êtes-vous sûr de n'avoir que 6 fichiers /home? Je serais à 100% certain que non.
Cry Havok
4

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 en cours, vous pouvez vous référer à d'autres réponses.

mouviciel
la source
1
Bonne idée en prenant en compte les liens difficiles. En supposant trouver GNU, vous n'avez pas besoin de tant d'étapes: find -printf '%i\n' | sort -u | wc -l. Si vous vouliez être portable, vous auriez find . -exec ls -id {} + | cut …plutôt besoin .
Gilles, arrête d'être mauvais le
2

OS X 10.6 étouffe 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
abeboparebop
la source
2

Je sais que je suis en retard pour la fête, mais je crois que cette bashsolution pure (ou autre shell qui accepte les doubles étoiles globales) 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

sortie:

d1/:    302
d2/:    24
d3/:    640
...
Jimmij
la source
1

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 à moins que les noms de fichiers incluent des nouvelles lignes.

Dennis Williamson
la source
beaucoup trop récursif ... Je veux seulement voir le niveau supérieur, où il totalise tout en dessous. totalisé ... cela finit par imprimer tous les répertoires.
xenoterracide
@xenoterracide: essayez d'ajouter -maxdepth 1immédiatement après le premier find. Si vous souhaitez inclure le nombre de sous-répertoires dans votre compte, supprimez-le -type fà la fin (cela aurait dû être le ! -type dcas de toute façon, de sorte que tous les fichiers autres que des répertoires auraient été inclus).
Dennis Williamson
1

Si vous en avez déjà ncduinstallé un (indispensable lorsque vous souhaitez effectuer un nettoyage), tapez simplement c"Activer / désactiver l'affichage du nombre d'éléments enfants". Et Cpour "Trier par articles".

Demi-Lune
la source
1
lol, ce doit être la réponse la plus généralement acceptée :)
x-yuri
0

du --inodes

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

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

Je suis sûr que cela résoudra le problème du PO. J'ai commencé à l'utiliser souvent pour savoir où se trouvent tous les fichiers indésirables de mes énormes disques (et les décharger sur un disque plus ancien).

Plus d'infos

Si vous ne voulez pas recurse (ce qui peut être utile dans d'autres situations), ajoutez

-S, --separate-dirs
Sridhar Sarnobat
la source