Коротка відповідь:
\ls -afq | wc -l
(Сюди входить .і ..віднімаємо 2.)
Коли ви перераховуєте файли в каталозі, можуть трапитися три поширені речі:
- Перерахування імен файлів у каталозі. Це неможливо: неможливо порахувати файли в каталозі без їх перерахування.
- Сортування імен файлів. Шкаралупа марок та
lsкоманда це роблять.
- Виклик
statдля отримання метаданих про кожен запис каталогу, наприклад, чи це каталог.
№3 - найдорожчий на сьогоднішній день, оскільки він вимагає завантаження inode для кожного файлу. Для порівняння, всі назви файлів, необхідні для №1, компактно зберігаються в декількох блоках. # 2 витрачає деякий час процесора, але це часто не є вимикачем угоди.
Якщо в іменах файлів немає нових рядків, простий ls -A | wc -lповідомляє, скільки файлів у каталозі. Будьте уважні, якщо у вас є псевдонім для lsцього, це може викликати виклик stat(наприклад, ls --colorабо ls -Fпотрібно знати тип файлу, для якого потрібен дзвінок stat), тому з командного рядка дзвоніть command ls -A | wc -lабо \ls -A | wc -lуникайте псевдоніму.
Якщо в імені файлу є нові рядки, то чи будуть вказані нові рядки чи ні, залежить від варіанту Unix. GNU coreutils та BusyBox за замовчуванням відображаються ?для нового рядка, тому вони безпечні.
Зателефонуйте, ls -fщоб перерахувати записи, не сортуючи їх (№2). Це автоматично включається -a(принаймні, в сучасних системах). -fВаріант в POSIX , але з додатковим статусом; більшість реалізацій підтримують його, але не BusyBox. Параметр -qзамінює символи, що не друкуються, включаючи нові рядки ?; це POSIX, але він не підтримується BusyBox, тому опустіть його, якщо вам потрібна підтримка BusyBox за рахунок перенарахування файлів, ім'я яких містить символ нового рядка.
Якщо в каталозі немає підкаталогій, то більшість версій findфайлу не вимагатиме statвведення його записів (оптимізація листового каталогу: каталог, що має кількість посилань 2, не може мати підкаталогів, тому findне потрібно шукати метадані записів, якщо тільки такий стан, як цього -typeвимагає). Таким чином find . | wc -l, це портативний, швидкий спосіб підрахунку файлів у каталозі за умови, що в каталозі немає підкаталогів і що жодне ім'я файлу не містить новий рядок.
Якщо в каталозі немає підкаталогів, але імена файлів можуть містити нові рядки, спробуйте один із них (другий повинен бути швидшим, якщо він підтримується, але може не помітно так).
find -print0 | tr -dc \\0 | wc -c
find -printf a | wc -c
З іншого боку, не використовуйте, findякщо у каталозі є підкаталоги: навіть find . -maxdepth 1дзвінки statпри кожному записі (принаймні, з GNU find та BusyBox find). Ви уникаєте сортування (№2), але ви платите ціну пошуку inode (# 3), яка вбиває продуктивність.
У оболонці без зовнішніх інструментів можна запустити підрахунок файлів у поточному каталозі set -- *; echo $#. При цьому пропущені крапки файлів (файли, ім'я яких починається з .) і повідомляє 1 замість 0 у порожній папці. Це найшвидший спосіб підрахунку файлів у невеликих каталогах, оскільки він не вимагає запуску зовнішньої програми, але (крім zsh) витрачає час на більші каталоги завдяки кроці сортування (№2).
В bash, це надійний спосіб підрахунку файлів у поточному каталозі:
shopt -s dotglob nullglob
a=(*)
echo ${#a[@]}
У ksh93 це надійний спосіб підрахунку файлів у поточному каталозі:
FIGNORE='@(.|..)'
a=(~(N)*)
echo ${#a[@]}
У zsh це надійний спосіб підрахунку файлів у поточному каталозі:
a=(*(DNoN))
echo $#a
Якщо у вас є mark_dirsнабір опцій, переконайтеся , щоб вимкнути його: a=(*(DNoN^M)).
У будь-якій оболонці POSIX це надійний спосіб підрахунку файлів у поточному каталозі:
total=0
set -- *
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
set -- .[!.]*
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
set -- ..?*
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
echo "$total"
Усі ці методи сортують назви файлів, за винятком zsh.
ls -l|wc -lбуло б вимкнене на один через загальну кількість блоків у першому рядкуls -lвипуску