30

I need to organise an external HDD such that there is no more than 500 folders on it. Ubuntu's "Properties" pane shows only the file count, not the folder count.

Is there a simple command line that will tell me the number of subdirectories?

I need to count recursively, and the drive is an external HDD mounted at /media/MUSIC/. It's for a car stereo system whose documentation says it only reads the first 500 folders.

0

9 Answers 9

25

Navigate to your drive (Can open a terminal window there) and simply execute:

ls -lR | grep ^d | wc -l
6
  • This appears to provide a more correct number than the answer I accepted 3 years ago. It counted the directory I was in whereas this done not. Aug 5, 2013 at 0:50
  • I see different numbers as well, but not too different.
    – SPRBRN
    Apr 16, 2014 at 12:49
  • Personally I prefer the grep -c over the wc -l. Maybe it's just me. Feb 15, 2016 at 15:17
  • 1
    The above will overcount if any directory entry contains the sequence \nd (where \n is the NL character). Feb 6, 2017 at 12:58
  • 1
    Toby is right, ls output is not supposed to be piped. Moreover this will be much slower because it has to output the whole tree and then run grep through it
    – phuclv
    Jun 17, 2018 at 17:04
38
  • Find all folders in total, including subdirectories:

    find /mount/point -type d | wc -l
    
  • Find all folders in the root directory (not including subdirectories):

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

    The -maxdepth 1 confines the command to the current directory (i.e., it forbids recursion); the -mindepth 1 causes it not to include the top-level directory (the mount point) itself.

6
  • That first one is exactly what I'm after. Thanks! Apr 9, 2010 at 6:07
  • @Dean: yeah, i've used it for counting directories in my music collection before too. :) for braggin' rights, count your MP3s: find /mount/point -type f | grep -i mp3 | wc -l Apr 9, 2010 at 6:17
  • 1
    @Dean: yeah, i don't know the find syntax offhand, but i'd usually use grep -v for that: find /mount/pt -type f | grep -vi mp3 | grep -vi wav | wc -l ...(and <i></i> doesn't work in comments, use *foo* to italicize: foo ) Apr 9, 2010 at 6:25
  • 2
    @Dean: i think you'd just use find /path -not -iname '*.mp3' | wc -l to filter MP3s, or to get both MP3s and WAVs use find /path -not -iname '*.mp3' -not -iname '*.wav' | wc -l Apr 9, 2010 at 6:28
  • 1
    Needed to add the -type f in order for it to ignore folders as well, but congrats! I just found a whole bunch of m4a files I had no idea about... Thanks! Apr 9, 2010 at 6:53
5

Newlines are valid characters in directory names. I suggest letting find print a character for each directory found and then letting wc count those characters:

find /mount/point -mindepth 1 -type d -printf 'a' | wc -c

Specify -mindepth 1 to avoid counting the mount point directory itself.

2
  • Counting things on a hard disk is probably an I/O-bound operation; this might be true even for a faster device like an SSD.  But, if CPU time is a concern, you should use wc -c rather than wc -l.  wc -c will use less slightly CPU time because it doesn’t need to look at every byte (and wc -l does).  And then, of course, if you’re counting bytes, you can use any one-byte string; it doesn’t have to be newline. Oct 25, 2020 at 16:01
  • @Scott Good point. I've now updated the answer. Oct 26, 2020 at 10:27
3

Try the following [but see below]:

ls -1 -Ap /mount/point | grep "/" | wc -l

Note: the first option to ls is dash one, but the option to wc is dash lower case L.

This will print a one-column list of the current directory (including . entries other than . and .. themselves), with trailing slashes for items that are subdirectories, then count the lines with the slashes.

If you want to look at the entire directory tree (i.e., look at the directory recursively), you should probably go with quack quixote's answer, as it is a little more explicit, but I've corrected mine (after taking quack's suggestions into account):

ls -ARp /mount/point | grep '/$' | wc -l
8
  • Need to add -R to go recursive (sorry for failing to mention), and need to specify the path to ls, but yeah, this works: ls -1 -p -R /media/MUSIC/ | grep "/" | wc -l Thanks! Apr 9, 2010 at 6:05
  • After trying both this and quack quixote's suggestion, I got 2 different results... I'm inclined to believe the other one. Thanks anyway! Apr 9, 2010 at 6:07
  • 1
    you don't need the -1 since ls will detect the pipe and won't format columns. also you can grab recursive listings with -R, but then you probably want to grep for "/$" to only match trailing slashes (or the count will be off). final version: ls -Rp | grep "/$" | wc -l Apr 9, 2010 at 6:10
  • 1
    the find version i posted will count . (ie /mount/point) in its count, the ls version in my above comment won't. those counts differ by 1, tho you could use /mount/point/* in the find command to correct that (assuming no hidden dot-directories). Apr 9, 2010 at 6:13
  • i'm not sure why you got the two differnent results, but @quack's method will include "hidden" directories (ie. those that begin with '.').
    – stuntmouse
    Apr 9, 2010 at 8:45
2

I have found du --inodes useful, but I'm not sure which version of du it requires. On Ubuntu 17.10, the following works:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Combine with | sort -nr to sort descending by number of containing inodes.

2

I have written ffcnt to speed up recursive file counting under specific circumstances: rotational disks and filesystems that support extent mapping.

It can be an order of magnitude faster than than ls or find based approaches.

1

When there is a large number of directories, tools like tree might take an eternity to finish or even hang, so you might want to use something more efficient.

The most efficient way to count the directories I can think of would be the following, since find will only print one . for each folder found instead of the complete path and file name and wc only needs to iterate over the number of characters:

find /mount/point -type d -printf '.' |wc -c

To exclude /mount/point itself from the calculation and only count the sub directories:

find /mount/point -mindepth 1 -type d -printf '.' |wc -c
0

I like to use tree to pull directory count with:

tree -d -R -fi --noreport | wc -l

Or, I'll use find to show bulk of the folders are located with:

find . -type d -printf "%h\n" | cut -d/ -f-2 | sort | uniq -c | sort -rn
1
  • Or something like: tree | grep -e '^.*directories,'
    – mindcrime
    Feb 17, 2016 at 23:49
-2

To find number of folders and directory in current directory, type the following command in your terminal:

echo */ | wc

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .