Коротка відповідь:
\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
випуску