Если вы знаете, что текущий каталог содержит хотя бы один не скрытый файл:
set -- *; echo "$#"
Это очевидно обобщается на любой шар.
В сценарии это иногда вызывает нежелательный побочный эффект перезаписи позиционных параметров. Вы можете обойти это, используя subshell или с помощью функции (версия Bourne / POSIX), например:
count_words () {
eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"
Альтернативное решение есть $(ls -d -- * | wc -l)
. Если глобус есть *
, команда может быть сокращена до $(ls | wc -l)
. Анализ выходных данных ls
всегда делает меня неловким, но здесь это должно работать до тех пор, пока ваши имена файлов не содержат символов новой строки или вы не можете ls
их избежать. И $(ls -d -- * 2>/dev/null | wc -l)
имеет преимущество в том, что изящно обрабатывает случай несовпадающего глобуса (т. Е. Возвращает 0 в этом случае, тогда как set *
метод требует тщательного тестирования, если глобус может быть пустым).
Если имена файлов могут содержать символы новой строки, альтернативой является использование $(ls -d ./* | grep -c /)
.
Любое из тех решений, которые полагаются на передачу расширения глобуса, ls
может завершиться ошибкой со слишком длинной ошибкой списка аргументов, если имеется много подходящих файлов.