Finding the leaves in a tree

I often have deep directory trees where I am only interested in the deepest layers and not the supporting sub directories. An example of this might be a music collection where you have moved all your albums into directories based on artist name, then album, then disk, then songs etc. I wanted a script to be able to display all the deepest directories in a directory tree. Take this tree as an example:

$find -type d
.
./x
./x/y
./x/y/z
./a
./a/b
./a/b/c
./1
./b
./b/b
./c
./c/c
./c/c/c
./c/c/c/c
./c/c/c/c/c
./c/c/c/c/c/c
./11
./11/2
./11/2/3
./11/1
./11/1/1
./11/1/1/1
./11/1/11
./11/11
./11/11/11
./z

I put this script together which cycles through the output of the find command looking for directories only and then compares this line to the previous one.

$ cat twigs
#!/bin/bash
LASTTWIG=""
for LINE in `find -type d`;do
 if [ ! "${LASTTWIG}" = "" ];then
   echo ${LINE} | grep ${LASTTWIG}/ > /dev/null
   if [ "$?" != "0" ]; then
     echo ${LASTTWIG}
   fi
  fi
  LASTTWIG=${LINE}
done
echo ${LASTTWIG}

The last echo is necessary to get the last directory which will always be a end of chain directory. The output gives something like this.

[user@localhost x]$ ./twigs
./x/y/z
./a/b/c
./1
./b/b
./c/c/c/c/c/c
./11/2/3
./11/1/1/1
./11/1/11
./11/11/11
./z
[user@localhost x]$

One strange issue I ran across when using a find -type d | while read LINE;do iteration was that the pipe caused the last line not to work as the variable was stored in a sub process as the pipe | executed the while loop in a sub shell. The post Variable Scope in Bash helped to clear it up.

This entry was posted in General and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *