web-dev-qa-db-fra.com

Quelle est la meilleure façon de compter les résultats "trouver"?

Ma solution actuelle serait find <expr> -exec printf '.' \; | wc -c, mais cela prend beaucoup trop de temps quand il y a plus de 10000 résultats. N'y a-t-il pas un moyen plus rapide/meilleur de le faire?

83
MechMK1

Essayez plutôt ceci (nécessite find '-printf soutien):

find <expr> -type f -printf '.' | wc -c

Ce sera plus fiable et plus rapide que de compter les lignes.

Notez que j'utilise le find de printf, pas une commande externe.


Bancs un peu:

$ ls -1
a
e
l
ll.sh
r
t
y
z

Mon point de repère snippet:

$ time find -type f -printf '.' | wc -c
8

real    0m0.004s
user    0m0.000s
sys     0m0.007s

Avec des lignes complètes:

$ time find -type f | wc -l
8

real    0m0.006s
user    0m0.003s
sys     0m0.000s

Donc ma solution est plus rapide =) (la partie importante est la ligne real)

60
Gilles Quenot

Pourquoi pas

find <expr> | wc -l

comme une solution portable simple? Votre solution originale est en créant un nouveau processusprintf pour chaque fichier individuel trouvé, et cela coûte très cher (comme vous venez de le trouver).

Notez que cela sera plus important si vous avez des noms de fichiers avec des nouvelles lignes intégrées, mais si vous en avez, alors je soupçonne que vos problèmes vont un peu plus loin :-)

116
Brian Agnew

Cette solution est certainement plus lente que d'autres find -> wc _ solutions ici, mais si vous aviez envie de faire autre chose avec les noms de fichiers en plus de les compter, vous pourriez read à partir de la sortie find.

n=0
while read -r -d ''; do
    ((n++)) # count
    # maybe perform another act on file
done < <(find <expr> -print0)
echo $n

C’est juste une modification de ne solution trouvée dans BashGuide qui gère correctement les fichiers avec des noms non standard en faisant du délimiteur de sortie find un octet NUL utilisant print0, et en lisant avec '' (Octet NUL) en tant que délimiteur de boucle.

4
John B

Ceci est ma fonction countfiles dans mon ~/.bashrc (il est relativement rapide, devrait fonctionner sous Linux et FreeBSD find, et ne se laisse pas berner par les chemins de fichiers contenant des caractères de nouvelle ligne; la dernière wc ne compte que des octets NUL):

countfiles () 
{ 
   command find "${1:-.}" -type f -name "${2:-*}" -print0 | 
       command tr -dc '\0' | command wc -c;
return 0
}

countfiles

countfiles ~ '*.txt'
2
carlo