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?
Réponses:
Essayez plutôt ceci (nécessite findle -printfsupport de):
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's printf, pas une commande externe.
Bancons un peu:
$ ls -1
a
e
l
ll.sh
r
t
y
z
Mon benchmark d'extrait:
$ 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 realligne)
-printf '.'
Pourquoi pas
find <expr> | wc -l
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.
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=0
while read -r -d ''; do
((n++)) # count
# maybe perform another act on file
done < <(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):
countfiles ()
{
command find "${1:-.}" -type f -name "${2:-*}" -print0 |
command tr -dc '\0' | command wc -c;
return 0
}
countfiles
countfiles ~ '*.txt'