user2566898
user2566898

Reputation: 1717

counting number of directories in a specific directory

How to count the number of folders in a specific directory. I am using the following command, but it always provides an extra one.

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

For example, if I have 3 folders, this command provides 4. If it contains 5 folders, the command provides 6. Why is that?

Upvotes: 159

Views: 334880

Answers (17)

Yury Euceda
Yury Euceda

Reputation: 566

If you want to count folders that have similar names like folder01,folder02,folder03, etc then you can do

ls -l | grep ^d | grep -c folder

Upvotes: -1

textral
textral

Reputation: 1049

Run stat -c %h folder and subtract 2 from the result. This employs only a single subprocess as opposed to the 2 (or even 3) required by most of the other solutions here (typically find or ls plus wc).

Using sh/bash:

echo $((`stat -c %h folder` - 2))   # 'echo' is a shell builtin

Using csh/tcsh:

@ cnt = `stat -c %h folder` - 2; echo $cnt   # 'echo' is a shell builtin


Explanation: stat -c %h folder prints the number of hardlinks to folder, and each subfolder under folder contains a ../ entry which is a hardlink back to folder. You must subtract 2 because there are two additional hardlinks in the count:

  1. folder's own self-referential ./ entry, and
  2. folder's parent's link to folder

Upvotes: 16

Arundev
Arundev

Reputation: 1934

To get the number of directories - navigate go to the directory and execute

 ls -l | grep -c ^d

Upvotes: 8

SO Stinks
SO Stinks

Reputation: 3408

The best answer to what you want is

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

this subtracts one to remove the unwanted '.' directory that find lists (as patel deven mentioned above).

If you want to count subfolders recursively, then just leave off the maxdepth option, so

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

PS If you find command substitution ugly, subtracting one can be done as a pure stream using sed and bc.

Subtracting one from count:

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

or, adding count to minus one:

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

Upvotes: 4

user1388547
user1388547

Reputation: 121

No of directory we can find using below command

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

Upvotes: 9

Brainmaniac
Brainmaniac

Reputation: 2536

If you only have directories in the folder and no files this does it:

ls | wc -l

Upvotes: 33

makassi
makassi

Reputation: 102

If you want to use regular expressions, then try:

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

Upvotes: 0

MTK
MTK

Reputation: 3570

Some useful examples:

count files in current dir

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

count dirs in current dir

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

count files and dirs in current dir

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

count files and dirs in in one subdirectory

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

I have noticed a strange thing (at least in my case) :

When I have tried with ls instead /bin/ls the -A parameter do not list implied . and .. NOT WORK as espected. When I use ls that show ./ and ../ So that result wrong count. SOLUTION : /bin/ls instead ls

Upvotes: 7

margenn
margenn

Reputation: 181

Count all files and subfolders, windows style:

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

Upvotes: 0

Anne van Rossum
Anne van Rossum

Reputation: 3149

Using zsh:

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

The N is a nullglob, / makes it match directories, # counts. It will neatly cope with spaces in directory names as well as returning 0 if there are no directories.

Upvotes: 3

Manoj
Manoj

Reputation: 201

Best way to do it:

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

This gives you the perfect count.

Upvotes: -2

briceburg
briceburg

Reputation: 822

I think the easiest is

  ls -ld images/* | wc -l

where images is your target directory. The -d flag limits to directories, and the -l flag will perform a per-line listing, compatible with the very familiar wc -l for line count.

Upvotes: 8

EmptyData
EmptyData

Reputation: 2576

Get a count of only the directories in the current directory

echo */ | wc

you will get out put like 1 309 4594

2nd digit represents no. of directories.

or

tree -L 1 | tail -1

Upvotes: 102

gniourf_gniourf
gniourf_gniourf

Reputation: 46813

A pure bash solution:

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

If you also want to count the hidden directories:

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

Note that this will also count links to directories. If you don't want that, it's a bit more difficult with this method.


Using find:

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

The trick is to output an x to stdout each time a directory is found, and then use wc to count the number of characters. This will count the number of all directories (including hidden ones), excluding links.


The methods presented here are all safe wrt to funny characters that can appear in file names (spaces, newlines, glob characters, etc.).

Upvotes: 4

shiyani suresh
shiyani suresh

Reputation: 896

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

For find -mindepth means total number recusive in directories

-maxdepth means total number recusive in directories

-type d means directory

And for wc -l means count the lines of the input

Upvotes: 49

Manish Shrivastava
Manish Shrivastava

Reputation: 32020

Best way to navigate to your drive and simply execute

ls -lR | grep ^d | wc -l

and to Find all folders in total, including subdirectories?

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

...or find all folders in the root directory (not including subdirectories)?

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

Cheers!

Upvotes: 13

Pavel Anossov
Pavel Anossov

Reputation: 62868

find is also printing the directory itself:

$ 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

You can instead test the directory's children and do not descend into them at all:

$ 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

You can also use 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

Upvotes: 136

Related Questions