user4556274 вже відповів на чому . Моя відповідь служить лише для надання додаткової інформації про те, як правильно рахувати файли.
У спільноті Unix загальна думка полягає в тому, що розбір результатів ls
- дуже погана ідея , оскільки назви файлів можуть містити контрольні або приховані символи. Наприклад, через символ нового рядка в імені файлу у нас єls | wc -l
сказали нам, що у виході ls
(який він є) є 5 рядків , але насправді у каталозі є лише 4 файли.
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
Спосіб №1: знайти корисність
find
Команда, яка , як правило , використовується для роботи навколо розбору імен файлів, може допомогти нам тут надрукувавши номер індексного дескриптора . Будь то каталог або файл, він має лише один унікальний номер inode. Таким чином, використовуючи -printf "%i\n"
та виключаючи .
через, -not -name "."
ми можемо мати точний підрахунок файлів. (Зверніть увагу на використання -maxdepth 1
для запобігання рекурсивного спуску в підкаталоги)
$> find -maxdepth 1 -not -name "." -print
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l
4
Спосіб №2: глоблстар
Простий, швидкий і переважно портативний спосіб:
$ set -- *
$ echo $#
228
set
команда використовується для встановлення позиційних параметрів оболонки ( $<INTEGER>
змінних, як у echo $1
). Це часто використовується для обходу /bin/sh
обмеження відсутніх масивів. Версію, яка виконує додаткові перевірки, можна знайти в Gille на Unix & Linux.
У оболонках, які підтримують масиви, наприклад bash
, ми можемо використовувати
items=( dir/* )
echo ${#items[@]}
як запропонував у коментарях steeldriver .
Аналогічний трюк find
методу, який використовувався wc
та globstar, можна використовувати stat
для підрахунку чисел у рядках у рядку:
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
Альтернативний підхід - використовувати підстановку в for
циклі. (Зауважте, цей тест використовує інший каталог, щоб перевірити, чи не підходить цей підхід до підкаталогів, а це не - 16 - це перевірена кількість елементів у моєму ~/bin
)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Метод №3: інші мови / перекладачі
Python також може вирішувати проблемні назви файлів, друкуючи довжину списку, заданого моєю os.listdir()
функцією (яка не є рекурсивною, і буде лише перелічувати елементи в каталозі, наведені як аргумент).
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4
Дивись також
ls | wc -l
не вдасться, якщо у назві файлу є файли з новим рядком. Це більш стійкий:find . -mindepth 1 -maxdepth 1 -printf . | wc -c