Quelle est la meilleure façon de compter les résultats de «recherche»?
99
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 de moyen plus rapide / meilleur de le faire?
Ce n'est pas plus fiable si l'indicateur -printf à rechercher n'est pas pris en charge sur votre plate-forme. ;-)
Randy Howard
7
Notez que vous pouvez réduire quelques nanosecondes de plus en ne citant pas le point dans-printf '.'
Jens
6
@Jens - surtout quand on prend en compte le temps nécessaire pour taper ça
Brian Agnew
6
Avec un si petit indice de référence, les délais sont probablement dominés par d'autres facteurs que ce que vous voulez mesurer. Une expérience avec un grand arbre serait plus utile. Mais cela me vaut mon vote pour faire ce que le PO a demandé.
tripleee
132
Pourquoi pas
find <expr>| wc -l
comme une simple solution portable? Votre solution d'origine génère un nouveau processusprintf pour chaque fichier individuel trouvé, et cela coûte très cher (comme vous venez de le trouver).
Notez que cela surclassera si vous avez des noms de fichiers avec des nouvelles lignes intégrées, mais si vous l'avez, je soupçonne que vos problèmes sont un peu plus profonds.
-1: se cassera sur le fichier avec les retours à la ligne, et c'est plus lent que de compter les octets =)
Gilles Quenot
21
Je ne pense pas que cela justifie un vote défavorable étant donné que la limitation du nom de fichier / nouvelle ligne est assez rare et notée ci-dessus. Ralentissez ? Peut-être. Étant donné que vous interrogez un système de fichiers, je soupçonne que la différence de vitesse est faible. Sur mes 10000 fichiers, je mesure une différence de 3 ms
Brian Agnew
8
La différence de performances entre 'find <expr> | wc -l' et 'find <expr> -printf. | wc -c 'sont extrêmement petits. La mise en cache (c'est-à-dire si vous exécutez la même recherche deux fois sur le même arbre) est beaucoup plus importante. IMHO la solution avec "wc -l" est beaucoup plus intuitive.
pitseeker
4
Cette solution est certainement plus lente que certaines des autres find -> wcsolutions ici, mais si vous étiez enclin à faire autre chose avec les noms de fichiers en plus de les compter, vous pourriez le faire à readpartir de la findsortie.
n=0while read -r -d '';do((n++))# count# maybe perform another act on filedone<<(find <expr>-print0)
echo $n
Il s'agit simplement d'une modification d' une solution trouvée dans BashGuide qui gère correctement les fichiers avec des noms non standard en faisant du finddélimiteur de sortie un octet NUL en utilisant print0et en lisant en utilisant ''(octet NUL) comme délimiteur de boucle.
C'est ma countfilesfonction dans mon ~/.bashrc(c'est raisonnablement rapide, devrait fonctionner pour Linux et FreeBSD find, et ne se laisse pas berner par les chemins de fichiers contenant des caractères de nouvelle ligne; le final wcne compte que les octets NUL):
Réponses:
Essayez plutôt ceci (nécessite
find
le-printf
support de):Ce sera plus fiable et plus rapide que de compter les lignes.
Notez que j'utilise le
find
'sprintf
, pas une commande externe.Bancons un peu:
Mon benchmark d'extrait:
Avec des lignes complètes:
Donc ma solution est plus rapide =) (la partie importante est la
real
ligne)la source
-printf '.'
Pourquoi pas
comme une simple solution portable? Votre solution d'origine génère un nouveau processus
printf
pour chaque fichier individuel trouvé, et cela coûte très cher (comme vous venez de le trouver).Notez que cela surclassera si vous avez des noms de fichiers avec des nouvelles lignes intégrées, mais si vous l'avez, je soupçonne que vos problèmes sont un peu plus profonds.
la source
Cette solution est certainement plus lente que certaines des autres
find -> wc
solutions ici, mais si vous étiez enclin à faire autre chose avec les noms de fichiers en plus de les compter, vous pourriez le faire àread
partir de lafind
sortie.Il s'agit simplement d'une modification d' une solution trouvée dans BashGuide qui gère correctement les fichiers avec des noms non standard en faisant du
find
délimiteur de sortie un octet NUL en utilisantprint0
et en lisant en utilisant''
(octet NUL) comme délimiteur de boucle.la source
C'est ma
countfiles
fonction dans mon~/.bashrc
(c'est raisonnablement rapide, devrait fonctionner pour Linux et FreeBSDfind
, et ne se laisse pas berner par les chemins de fichiers contenant des caractères de nouvelle ligne; le finalwc
ne compte que les octets NUL):la source