163 votes

Comptage rapide des fichiers Linux pour un grand nombre de fichiers

J'essaie de trouver la meilleure façon de trouver le nombre de fichiers dans un répertoire particulier lorsqu'il y a un très grand nombre de fichiers ( > 100 000).

Lorsqu'il y a autant de fichiers, l'exécution de "ls | wc -l" prend un temps assez long. Je pense que c'est parce qu'il renvoie les noms de tous les fichiers. J'essaie d'utiliser le moins d'entrées-sorties possible sur le disque.

J'ai expérimenté avec quelques scripts shell et Perl, sans succès. Avez-vous des idées ?

218voto

mark4o Points 20472

Par défaut ls trie les noms, ce qui peut prendre un certain temps s'il y en a beaucoup. De plus, il n'y aura pas de sortie tant que tous les noms n'auront pas été lus et triés. Utilisez l'option ls -f pour désactiver le tri.

ls -f | wc -l

Notez que cela permettra également -a donc . , .. et d'autres fichiers commençant par . seront comptabilisés.

38voto

igustin Points 572

Avez-vous essayé de trouver ? Par exemple :

find . -name "*.ext" | wc -l

20voto

Thomas Points 362

Find, ls et perl testés contre 40 000 fichiers : même vitesse (bien que je n'aie pas essayé de vider le cache) :

[user@server logs]$ time find . | wc -l
42917

real    0m0.054s
user    0m0.018s
sys     0m0.040s
[user@server logs]$ time /bin/ls -f | wc -l
42918

real    0m0.059s
user    0m0.027s
sys     0m0.037s

et avec perl opendir/readdir, même temps :

[user@server logs]$ time perl -e 'opendir D, "."; @files = readdir D; closedir D; print scalar(@files)."\n"'
42918

real    0m0.057s
user    0m0.024s
sys     0m0.033s

note : J'ai utilisé /bin/ls -f pour être sûr de contourner l'option alias qui pourrait ralentit un peu et -f pour éviter le classement des fichiers. ls sans -f est deux fois plus lent que find/perl sauf si ls est utilisé avec -f, cela semble être le même temps :

[user@server logs]$ time /bin/ls . | wc -l
42916

real    0m0.109s
user    0m0.070s
sys     0m0.044s

J'aimerais aussi avoir un script pour demander directement au système de fichiers sans toutes les informations inutiles.

tests basés sur les réponses de Peter van der Heijden, glenn jackman et mark4o.

Thomas

8voto

Gutza Points 1353

Étonnamment pour moi, un simple find est très comparable à ls -f.

> time ls -f my_dir | wc -l
17626

real    0m0.015s
user    0m0.011s
sys     0m0.009s

contre

> time find my_dir -maxdepth 1 | wc -l
17625

real    0m0.014s
user    0m0.008s
sys     0m0.010s

Bien sûr, les valeurs de la troisième décimale changent un peu à chaque fois que vous exécutez l'une de ces fonctions, mais elles sont fondamentalement identiques. Remarquez cependant que find renvoie une unité supplémentaire, car il compte le répertoire lui-même (et, comme mentionné précédemment, ls -f renvoie deux unités supplémentaires, puisqu'il compte également . et ..).

5voto

mightybs Points 151

Vous pouvez modifier la sortie en fonction de vos besoins, mais voici un one-liner bash que j'ai écrit pour compter et rapporter récursivement le nombre de fichiers dans une série de répertoires nommés numériquement.

dir=/tmp/count_these/ ; for i in $(ls -1 ${dir} | sort -n) ; { echo "$i => $(find ${dir}${i} -type f | wc -l),"; }

Cette commande recherche récursivement tous les fichiers (pas les répertoires) dans le répertoire donné et retourne les résultats dans un format de type hachage. De simples modifications de la commande find pourraient rendre plus spécifique le type de fichiers que vous cherchez à compter, etc.

Cela donne quelque chose comme ça :

1 => 38,
65 => 95052,
66 => 12823,
67 => 10572,
69 => 67275,
70 => 8105,
71 => 42052,
72 => 1184,

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X