Use GNU find to show only the leaf directories

You can use -links if your filesystem is POSIX compliant (ie, a directory has a link for each subdirectory in it, a link from its parent and a link to self, thus a count of 2 link if it has no subdirectories).

The following command should do what you want:

find dir -type d -links 2

However, it does not seems to work on Mac OS X (as @Piotr mentionned). Here is another version that is slower, but does work on Mac OS X. It is based on his version, with correction to handle whitespace in directory names:

find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;

I just found another solution to this that works on both Linux & macOS (without find -exec)!

It involves sort (twice) and awk:

find dir -type d | sort -r | awk 'a!~"^"$0{a=$0;print}' | sort

Explanation:

  1. sort the find output in reverse order

    • now you have subdirectories appear first, then their parents
  2. use awk to omit lines if the current line is a prefix of the previous line

    • (this command is from the answer here)
    • now you eliminated "all parent directories" (you're left with parent dirs)
  3. sort them (so it looks like the normal find output)
  4. Voila! Fast and portable.

@Sylvian solution didn't work for me on mac os x for some obscure reason. So I've came up with a bit more direct solution. Hope this will help someone:

find . -type d  -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;

Explanation:

  • ls -p ends directories with '/'
  • so (ls -p XXX | grep / >/dev/null) returns 0 if there is no directories
  • -print0 && -0 is to make xargs handle spaces in directory names