Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use GNU find to show only the leaf directories

Tags:

find

bash

shell

gnu

I'm trying to use GNU find to find only the directories that contain no other directories, but may or may not contain regular files.

My best guess so far has been:

find dir -type d \( -not -exec ls -dA ';' \)

but this just gets me a long list of "."

Thanks!

like image 932
Thomas G Henry Avatar asked Nov 24 '10 17:11

Thomas G Henry


2 Answers

You can use -links if your filesystem is POSIX compliant (i.e. a directory has a link for each subdirectory in it, a link from its parent and a link to itself, thus a count of 2 links 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 mentioned). Here is another version that is slower, but does work on Mac OS X. It is based on his version, with a correction to handle whitespace in directory names:

find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;
like image 92
Sylvain Defresne Avatar answered Oct 16 '22 06:10

Sylvain Defresne


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.
like image 24
ahmet alp balkan Avatar answered Oct 16 '22 07:10

ahmet alp balkan