подсчет количества каталогов в определенном каталоге

103

Как посчитать количество папок в конкретном каталоге. Я использую следующую команду, но она всегда предоставляет дополнительную.

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

Например, если у меня 3 папки, эта команда предоставляет 4. Если содержит 5 папок, команда предоставляет 6. Почему?

user2566898
источник
4
Дополнительный счет на 1 возникает из-за текущего каталога '.' , что также учитывается словом find.
Патель Девен

Ответы:

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 и count () результат.
Pilipe
1
ls -l | grep -c ^dмертво просто и работает. @Pathros, вероятно, есть лучший способ в PHP, но в худшем случае в PHP вы всегда можете использовать функцию shell_exec () для выполнения командной строки и возврата результатов в строку. ie $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte
66

Получить подсчет только каталогов в текущем каталоге

echo */ | wc

ты выйдешь, как 1 309 4594

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

или

tree -L 1 | tail -1

EmptyData
источник
8
К сожалению, это не удается, если в именах директорий есть пробелы.
Майкл Кэмпбелл,
zsh: no matches found: */нуждается в nullglob
Энн ван Россум
@AnnevanRossum У вас есть echo. типwhich echo
EmptyData
7
Первый может быть немного улучшен:echo */ | wc -w
ibic
Nota , что это будет считаться 1 , если нет каталогов вместо 0.
jinawee
27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Для поиска -mindepthозначает общее количество в каталогах

-maxdepth означает общее количество в каталогах

-type d означает каталог

А для wc -lсредств подсчитайте строки ввода

Шияни Суреш
источник
2
Не могли бы вы объяснить свой ответ (внутри вашего ответа)?
Zulu
-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
Brainmaniac
источник
2
Это также файлы, но вопрос был о папках / каталогах.
Роберт
12

Лучший способ перейти к вашему диску и просто выполнить

ls -lR | grep ^d | wc -l

а Найти все папки вместе, включая подкаталоги?

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

... или найти все папки в корневом каталоге (не включая подкаталоги)?

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

Ура!

Маниш Шривастава
источник
Обратите внимание, что предыдущие ls -lRигнорируют каталог с префиксом точки при их find -type d подсчете. Таким образом, счетчик, заданный первой командой, неверен, если у вас есть каталоги с префиксом точки (например, у вас есть подкаталог .git!). Вы не можете просто использовать, -lRaпотому что вы также получаете для каждого каталога a .и ..запись. Это также относится к ответу @Pavel Anossov
marcz
12

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

Используя sh / bash:

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

Используя csh / tcsh:

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


Объяснение: stat -c %h folderпечатает количество жестких ссылок на папку , и каждая подпапка в папке содержит запись ../, которая является жесткой ссылкой на папку . Вы должны вычесть 2, потому что в счетчике есть две дополнительные жесткие ссылки:

  1. собственная ссылка на папку ./ entry, и
  2. папка , родительская в ссылку на папку
текстральный
источник
В связи с этим вопросом: [Почему в новом каталоге жестко установлено 2 ссылок, прежде чем в него что-либо будет добавлено? ] ( unix.stackexchange.com/questions/101515 ) Это объясняет, почему это отличный ответ. К сожалению, этому не было уделено должного внимания! Хотя это хороший ответ, результат, к сожалению, зависит от файловой системы, но для большинства распространенных файловых систем это сработает.
квантур
8

Я думаю, что самое простое это

  ls -ld images/* | wc -l

где imagesваш целевой каталог. Флаг -d ограничивает каталоги, а флаг -l выполняет листинг для каждой строки, совместимый с хорошо знакомым wc -lдля подсчета строк.

Briceburg
источник
Также возвращает результат +1
Йозефа
1
Согласно man ls, -ddoes: «перечисляет сами каталоги, а не их содержимое», то есть, если вы запустите ls /tmp, вы получите то, что есть /tmp, а если вы запустите, ls -d /tmpвы просто получите /tmp. -dКоммутатор не фильтровать каталоги, как и было запрошено.
Роберт
5

Несколько полезных примеров:

подсчитать файлы в текущем каталоге

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

считать каталоги в текущем каталоге

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

подсчитать файлы и каталоги в текущем каталоге

/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

MTK
источник
4

Нет каталога, который мы можем найти, используя команду ниже

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

user1388547
источник
Просто ls -l | grep ^d | wc -lбудет делать, нет необходимости использовать "здесь
kaspiotr
3

Решение на чистом bash:

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

Хитрость заключается в том, чтобы выводить xна стандартный вывод каждый раз, когда каталог найден, а затем использовать wcдля подсчета количества символов. Будет подсчитано количество всех каталогов (включая скрытые), исключая ссылки.


Представленные здесь методы безопасны по отношению к забавным символам, которые могут появляться в именах файлов (пробелы, новые строки, символы глобуса и т. Д.).

gniourf_gniourf
источник
Это лучшее решение, представленное в этом вопросе, и оно будет работать всегда!
квантур
3

Использование zsh:

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

Это Nнульглоб, /заставляет его соответствовать каталогам, #считает. Он аккуратно справится с пробелами в именах каталогов, а также вернется, 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"
Margenn
источник
0

Если вы хотите использовать регулярные выражения, попробуйте:

ls -c | grep "^d" | wc -l
макасси
источник
1
Хотите добавить пояснение к ответу, состоящему только из кода? Это помогло бы бороться с неправильным представлением о том, что StackOverflow - это бесплатный сервис для написания кода. Также загляните сюда, чтобы улучшить внешний вид: stackoverflow.com/editing-help
Юннош
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
Доктор Человек Персона II
источник
-1

Лучший способ сделать это:

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

Это дает вам идеальный счет.

Манодж
источник
6
Вы имеете в виду, что это худший способ сделать это! кроме того, это не учитывает количество каталогов. А что, если есть имя каталога, содержащее строку total? ваш метод не работает :(. Не разбирайтеls !
gniourf_gniourf