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 find
le -printf
support 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 real
ligne)
-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 -> 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 la find
sortie.
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 find
délimiteur de sortie un octet NUL en utilisant print0
et en lisant en utilisant ''
(octet NUL) comme délimiteur de boucle.
C'est ma countfiles
fonction 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 wc
ne 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'