підрахунок кількості каталогів у певному каталозі


103

Як підрахувати кількість папок у певному каталозі. Я використовую таку команду, але вона завжди надає додаткову.

find /directory/ -maxdepth 1 -type d -print| wc -l

Наприклад, якщо у мене є 3 папки, ця команда забезпечує 4. Якщо вона містить 5 папок, команда надає 6. Чому це?


4
Додатковий 1 рахунок існує через поточний каталог '.' , що також враховується «знайти».
patel deven

Відповіді:


94

find також друкує сам каталог:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

Ви можете замість цього тестувати дітей каталогу і зовсім не спускатись до них:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

Ви також можете використовувати ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

Приємно! Як би ви це зробили $ ls -l .vimз PHP? Або як отримати лише загальну суму, без списку. Я маю на увазі, в цьому випадку дістати тільки 52?
Патрос

Ха-ха. Мені подобається, як аргумент проти PowerShell полягає в тому, що BASH легше всіляко ... хочете побачити команду POSH, щоб це зробити? (ls).Count
Калонь Колоб

@Pathros Використання Glob з прапором GLOB_ONLYDIR і підрахунку () результат.
Піліпе

1
ls -l | grep -c ^dмертвий простий і працює. @Pathros, можливо, є кращий спосіб у PHP, але в гіршому випадку в PHP ви завжди можете використовувати функцію shell_exec () для виконання командного рядка та повернення результатів у рядок. тобто $dirCount = shell_exec('ls -l | grep -c ^d');
гігабайт

66

Отримайте кількість лише каталогів у поточному каталозі

echo */ | wc

ви вийдете поставити як 1 309 4594

2nd digitпредставляє ні. довідників.

або

tree -L 1 | tail -1


8
Це не вдається, якщо, на жаль, є пробіли в назвах dir.
Майкл Кемпбелл

zsh: no matches found: */потрібен nullglob
Енн ван Россум

@AnnevanRossum У вас є echo. типwhich echo
EmptyData

7
Перший можна ще трохи покращити:echo */ | wc -w
ibic

Зазначимо, що це буде рахувати 1, якщо немає каталогів замість 0.
jinawee

27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Для пошуку -mindepthозначає загальна кількість повторюваних в каталогах

-maxdepth означає загальну кількість повторюваних в каталогах

-type d довідник засобів

А для wc -lзасобів підрахуйте рядки введення


2
Чи можете ви пояснити свою відповідь будь-ласка (всередині своєї відповіді)?
Зулу

-mindepth означає загальну кількість відштовхувальних в каталогах, -maxdepth означає загальну кількість рекусивних у каталогах, -type d означає каталог, а wc -l означає кількість рядків із заданого переліку каталогів
shiyani suresh

find . -mindepth 1 -maxdepth 1 -type d | wc -lдасть вам багато пробілів між числом, наприклад: `2` ви можете запобігти цьому, скориставшись цим: dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 і може бути корисним для таких умов, як:if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
naorz

16

Якщо у папці є лише каталоги, а файлів немає, це робиться так:

ls | wc -l

2
Тут також потрапляють файли, але питання стосувалося папок / каталогів.
Роберт

12

Найкращий спосіб перейти до свого накопичувача та просто виконати

ls -lR | grep ^d | wc -l

а також знайти всі папки, включаючи підкаталоги?

find /mount/point -type d | wc -l

... або знайти всі папки в кореневій директорії (не включаючи підкаталоги)?

find /mount/point -maxdepth 1 -type d | wc -l

Ура!


Зауважте, що попередні l ігнорують дофіксований -lRкаталог точок під час їх find -type dпідрахунку. Отже, підрахунок, заданий першою командою, помиляється, якщо у вас є дофіксовані каталоги (наприклад, у вас є підкаталог .git!). Ви не можете просто використовувати, -lRaтому що ви також отримуєте для кожного каталогу а .та ..запис. Це стосується також відповіді @Pavel Anossov
marcz

12

Виконайте stat -c %h folderі відніміть 2 від результату. Для цього використовується лише один підпроцес на відміну від 2 (або навіть 3), необхідних більшості інших рішень тут (як правило, findплюс wc).

Використання sh / bash:

cnt = $ ((`stat -c% h папка` - 2))
echo $ cnt # 'echo' - це вбудований sh / bash, а не додатковий процес

Використання csh / tcsh:

@ cnt = `stat -c% h папка` - 2
echo $ cnt # 'echo' - це вбудований файл csh / tcsh, а не додатковий процес


Пояснення: stat -c %h folderдрукує кількість жорстких посилань на папку , і кожна підпапка в папці містить запис ../, який є твердою посиланням назад до папки . Ви повинні відняти 2, оскільки в рахунку є дві додаткові тверді посилання:

  1. власний самореференційний запис папки ./ та
  2. папка , батьківська на заслання на папку

Пов’язане з цим питанням: [Чому новий каталог має кількість важких посилань 2, перш ніж до нього щось додано? ] ( unix.stackexchange.com/questions/101515 ) Пояснюється, чому це чудова відповідь. На жаль, це не приділяло достатньої уваги! Хоча це хороша відповідь, результат її залежить, на жаль, від файлової системи, але для більшості поширених файлових систем це спрацює.
квантур

8

Я думаю, що найпростіше

  ls -ld images/* | wc -l

де imagesваш цільовий каталог. Прапор -d обмежується каталогами, а прапор -l виконує перелік рядків, сумісний із дуже звичним wc -lдля кількості рядків.


Також повертає результат +1
josef

1
Відповідно man ls, -dробить: "перераховуйте самі каталоги, а не їх вміст", тобто якщо ви запустите ls /tmp, ви отримаєте те, що є /tmp, а якщо запустите, ls -d /tmpви просто отримаєте /tmp. -dКомутатор не фільтрувати каталоги, як і було запрошено.
Роберт

5

Деякі корисні приклади:

підрахунок файлів у поточному режимі

/bin/ls -lA  | egrep -c '^-'

порахуй дріс в поточному dir

/bin/ls -lA  | egrep -c '^d'

підраховувати файли та dirs у поточному dir

/bin/ls -lA  | egrep -c '^-|^d'

підраховуйте файли та файли в одному підкаталозі

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

Я помітив дивну річ (принаймні в моєму випадку):

Коли я спробував, lsзамість /bin/ls цього -Aпараметр do not list implied . and ..НЕ ПРАЦЮЄ, як очікується. Коли я використовую lsце шоу ./ і ../, тож результат неправильно підраховується. РІШЕННЯ: /bin/lsнатомістьls


4

Жоден каталог, який ми можемо знайти за допомогою команди нижче

ls -l | grep "^d" | wc -l


Просто ls -l | grep ^d | wc -lбуде робити, немає необхідності використовувати "тут
kaspiotr

3

Чистий розчин баш:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Якщо ви також хочете порахувати приховані каталоги:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Зауважте, що це також буде рахувати посилання на каталоги. Якщо ви цього не хочете, з цим методом трохи складніше.


Використання find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

Підхід полягає в тому, щоб виводити xstdout кожен раз, коли знайдеться каталог, а потім використовувати wcдля підрахунку кількості символів. При цьому буде підраховано кількість усіх каталогів (включаючи приховані), за винятком посилань.


Методи, представлені тут, - це безпечний Wrt для смішних символів, які можуть з'являтися у назвах файлів (пробіли, нові рядки, глобальні символи тощо).


Це найкраще рішення, представлене в цьому питанні, і буде працювати завжди!
квантур

3

Використання zsh:

a=(*(/N)); echo ${#a}

Це Nnullglob, /змушує його відповідати каталогам, #рахувати. Він акуратно впорається з пробілами в назвах каталогів, а також повернеться, 0якщо немає каталогів.


0

Порахуйте всі файли та папки, стиль Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"

0

Якщо ви хочете використовувати регулярні вирази, то спробуйте:

ls -c | grep "^d" | wc -l

1
Ви хочете додати пояснення до відповіді, що стосується лише коду? Це допоможе боротися з помилковим уявленням про те, що StackOverflow - це безкоштовна послуга написання коду. Крім того , подивіться тут , щоб поліпшити зовнішній вигляд: stackoverflow.com/editing-help
Yunnosch

0

Найкраща відповідь на те, що ти хочеш

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

це віднімає один для видалення небажаного '.' каталог, у якому знаходять списки (як згаданий вище patel deven).

Якщо ви хочете рекурсивно рахувати підпапки, тоді просто залиште параметр maxdepth

echo `find . -type d | wc -l`-1 | bc

PS Якщо ви вважаєте заміну команди некрасивою, віднімання можна зробити як чистий потік, використовуючи sedі bc.

Віднімання одного з числа:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

або, додавши рахунок до мінус одного:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc

-1

Найкращий спосіб зробити це:

ls -la | grep -v total | wc -l

Це дає вам ідеальну кількість.


6
Ти маєш на увазі, що це гірший спосіб зробити це! до того ж, це не враховує кількість каталогів. А що робити, якщо є ім'я каталогу, яке містить рядок total? ваш метод порушений :(. Не розбирайтеls !
gniourf_gniourf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.