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 findel -printfsoporte):
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 reallí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 countfilesfunció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 wcsolo 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 -> wcsoluciones aquí, pero si estuviera dispuesto a hacer algo más con los nombres de los archivos además de contarlos, podría hacerlo readdesde la findsalida.
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 finddelimitador de salida sea un byte NUL usando print0y leyéndolo usando ''(byte NUL) como delimitador de bucle.