Si sabe que el directorio actual contiene al menos un archivo no oculto:
set -- *; echo "$#"
Esto es obviamente generalizable a cualquier glob.
En un guión, esto tiene el efecto secundario a veces desafortunado de sobrescribir los parámetros posicionales. Puede solucionarlo utilizando una subshell o con una función (versión Bourne / POSIX) como:
count_words () {
eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"
Una solución alternativa es $(ls -d -- * | wc -l). Si el glob es *, el comando se puede acortar a $(ls | wc -l). Analizar la salida de lssiempre me hace sentir incómodo, pero aquí debería funcionar siempre y cuando los nombres de los archivos no contengan nuevas líneas o lsse les escapen. Y $(ls -d -- * 2>/dev/null | wc -l)tiene la ventaja de manejar el caso de un globo no coincidente con gracia (es decir, devuelve 0 en ese caso, mientras que el set *método requiere pruebas complejas si el globo puede estar vacío).
Si los nombres de archivo pueden contener caracteres de nueva línea, se debe utilizar una alternativa $(ls -d ./* | grep -c /).
Cualquiera de esas soluciones que se basan en pasar la expansión de un globo lspuede fallar con un error de lista de argumentos demasiado largo si hay muchos archivos coincidentes.