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 ls
siempre me hace sentir incómodo, pero aquí debería funcionar siempre y cuando los nombres de los archivos no contengan nuevas líneas o ls
se 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 ls
puede fallar con un error de lista de argumentos demasiado largo si hay muchos archivos coincidentes.