If you only want a single level, then there is a trick to doing this without having to enumerate the directory. If you want recursion, then what you've got is the best you're going to get.
The single level trick:
stat --printf='%h\n' /path/to/dir
...and subtract 2. The result is the number of directories within that directory (non recursive).
That command shows the number of hard links on the specified file. Whenever you create a directory inside a directory, the sub directory has a hard link entry to the parent directory, the ..
. So by creating a sub directory, you increase the number of hard links to the parent directory by one. But we subtract 2 because every directory starts off with 2 hardlinks. One hardlink is in the parent directory and points to it: the dir
entry inside /path/to
. The other hardlink is the directory containing a link to itself: the .
entry.
However with recursion, you have to examine each directory. The problem is that there's no way to say "give me a list of only directories within this directory". You have to get a list of every single entry in the directory, and then stat
each one to find out if it's a directory or a file.
Now when you stat the directory, you can use the above hardlink trick to find if that directory contains any sub directories, and thus you can save yourself a little bit of time and not descend into that directory. The find
utility actually uses this trick to get a little performance gain in the process.
So basically, using find
is going to be the best you can do if you want recursion.
find
command on a directory structure containing 211G of data on a local disk and it took 0.952 seconds of CPU time. – John1024 Feb 24 '14 at 05:39du
never completed? Can you post the out ofdf -Ti
on all the filesystems mounted at or bellow.
? – Stéphane Chazelas Feb 24 '14 at 10:50