Il n'est pas rare que je doive compter le nombre de fichiers dans un répertoire, parfois cela se compte en millions.
Existe-t-il un meilleur moyen que de simplement les énumérer et de les compter find . | wc -l
? Y a-t-il une sorte d'appel de système de fichiers que vous pouvez faire sur ext3 / 4 qui nécessite moins d'E / S?
linux
filesystems
find
ext4
MattPark
la source
la source
find -maxdepth 1
. Notez qu'avec votre approche actuelle, vous compterez deux fois n'importe quel nom contenant un caractère de nouvelle ligne.Réponses:
Pas une accélération fondamentale mais au moins quelque chose :)
Vous n'avez vraiment pas besoin de passer la liste des noms de fichiers, juste les sauts de ligne suffisent. Cette variante est environ 15% plus rapide sur mon Ubuntu 12.04.3 lorsque les répertoires sont mis en cache dans la RAM. De plus, cette variante fonctionnera correctement avec des noms de fichiers contenant des retours à la ligne.
Fait intéressant, cette variante semble être un peu plus lente que celle ci-dessus:
Cas particulier - mais vraiment rapide
Si le répertoire est sur son propre système de fichiers, vous pouvez simplement compter les inodes:
Si le nombre de répertoires et de fichiers dans d'autres répertoires que celui compté ne change pas grand-chose, vous pouvez simplement soustraire ce nombre connu du
df -i
résultat actuel . De cette façon, vous pourrez compter les fichiers et répertoires très rapidement.la source
time find /usr/src/ -printf \\n | wc -l
, vous pouvez vider les caches entre les runs avecsudo sync && sudo sysctl -w vm.drop_caches=3
-printf x
censé être le même que-printf '\0'
? Je ne le vois pas mentionné dans les documents.-printf
fonctionne de manière similaire à laprintf()
fonction en C avec la principale différence que les%
directives ont une signification différente. L'action est invoquée pour chaque fichier trouvé. Cela signifie que-printf x
va imprimer le caractèrex
pour chaque fichier trouvé (essayez-le!) Et-printf '\0'
imprimera le caractère NULL (code ASCII 0) pour chaque fichier trouvé.-printf '\0'
n'a pas de signification particulière. Les deux fonctionneront de la même manière dans l'exemple avecwc -c
dans cette réponse.J'ai écrit ffcnt exactement dans ce but. Il récupère l'offset physique des répertoires eux-mêmes avec l'
fiemap
ioctl, puis planifie la traversée du répertoire en plusieurs passes séquentielles pour réduire l'accès aléatoire. Que vous obteniez réellement une accélération par rapport àfind | wc
dépend de plusieurs facteurs:fiemap
ioctl bénéficieront le plusle (re) montage avec
relatime
ou mêmenodiratime
peut également améliorer la vitesse (pour toutes les méthodes) lorsque les accès entraîneraient autrement des mises à jour des métadonnées.la source
En fait, sur mon système (Arch Linux) cette commande
est plus rapide que tout ce qui précède:
la source
/bin/ls: Argument list too long
si vous utilisez la globalisation, mais là encore il peut fonctionner de manière récursive comme find aussi, donc c'est peut-être quelque chose à considérer, n'utilisez pas find si ce n'est pas nécessaire.ls -A
lister uniquement les fichiers dans le répertoire courant alors quefind
sans-maxdepth 1
argument fera une recherche récursive dans tous les sous-répertoires.