Mi solución actual sería find <expr> -exec printf '.' \; | wc -c
, pero esto lleva demasiado tiempo cuando hay más de 10000 resultados. ¿No hay una forma mejor o más rápida de hacer esto?
Respuestas:
Intente esto en su lugar (requiera find
el -printf
soporte):
find <expr> -type f -printf '.' | wc -c
Será más confiable y rápido que contar las líneas.
Tenga en cuenta que utilizo find
's printf
, no un comando externo.
Hagamos la banca un poco:
$ ls -1
a
e
l
ll.sh
r
t
y
z
Mi punto de referencia de fragmentos:
$ time find -type f -printf '.' | wc -c
8
real 0m0.004s
user 0m0.000s
sys 0m0.007s
Con líneas completas:
$ time find -type f | wc -l
8
real 0m0.006s
user 0m0.003s
sys 0m0.000s
Entonces mi solución es más rápida =) (la parte importante es la real
línea)
-printf '.'
Por qué no
find <expr> | wc -l
como una simple solución portátil? Su solución original está generando un nuevo proceso printf
para cada archivo individual encontrado, y eso es muy costoso (como acaba de descubrir).
Tenga en cuenta que esto contará en exceso si tiene nombres de archivo con nuevas líneas incrustadas, pero si tiene eso, sospecho que sus problemas son un poco más profundos.
Esta es mi countfiles
función en mi ~/.bashrc
(es razonablemente rápida, debería funcionar para Linux y FreeBSD find
, y no se deja engañar por las rutas de archivo que contienen caracteres de nueva línea; la final wc
solo cuenta bytes NUL):
countfiles ()
{
command find "${1:-.}" -type f -name "${2:-*}" -print0 |
command tr -dc '\0' | command wc -c;
return 0
}
countfiles
countfiles ~ '*.txt'
Esta solución es ciertamente más lenta que algunas de las otras find -> wc
soluciones aquí, pero si estuviera dispuesto a hacer algo más con los nombres de los archivos además de contarlos, podría hacerlo read
desde la find
salida.
n=0
while read -r -d ''; do
((n++)) # count
# maybe perform another act on file
done < <(find <expr> -print0)
echo $n
Es solo una modificación de una solución que se encuentra en BashGuide que maneja correctamente archivos con nombres no estándar al hacer que el find
delimitador de salida sea un byte NUL usando print0
y leyéndolo usando ''
(byte NUL) como delimitador de bucle.