LJ Archive

dtree

Phil Hughes

Issue #29, September 1996

dtree is a utility that will display a directory hierarchy or tree.

While Linux comes with hundreds of utilities, something you got used to on another system always seems to be missing. One program in this category is something that will display a directory hierarchy or tree.

While some file managers that run under X-Windows will do this sort of task, it is sometimes very handy to have a command-line version. While not Linux-specific, the dtree utility is such a program.

I will first explain how to use dtree, then explain how it works. If you invoke it by just entering its name it will display the directory hierarchy starting at the current directory. If you invoke it with an argument, that argument is used as the starting directory. For example, if you enter dtree /home/fyl/Cool, a tree of directories under /home/fyl/Cool will be displayed.

dtree is written in the finest old-time Unix tradition using common utilities with a short shell script to glue them together. Here is the program:

: dtree
: dtree
# print a hierarchy tree starting at
# specified directory (. default)
(cd ${1-.}; pwd)
find ${1-.} -type d -print | sort -f |
sed -e "s,^${1-.},," -e "/^$/d" -e \
"s,[^/]*/\([^/]*\)$,\`-----\1," -e "s,[^/]*/,|      ,g"

Before you panic, remember, it is only four lines plus comments. It can't be that hard to figure out. The first step is to run the program and produce some sample output. If you don't have a computer at hand-or want to see what it does before you become a believer-I have included what I get by running it in my current directory (/home/fyl/LJ).

/home/fyl/LJ
`-----Advertising
`-----Ams
`-----Ams.old
`-----Angoss
|     `-----Orig
|     `-----Shots
`-----Artsys
`-----Buyer
`-----Caldera
`-----Employee
`-----Fms
`-----Jobs
`-----ljml.d
|      `-----src.d
|      `-----tst.d
`-----OSW
`-----Posts
`-----Presentations
|       `-----Amus
|       `-----Boston
|       `-----Cjk
|       `-----Decus
|       |        `-----Old
|       |        `-----Vancouver.96
|       `-----UW
`-----Progs
`-----Related
`-----Work
`-----Write

The first line in the output is the name of the directory dtree was run on. This line was produced by the line that begins with (cd. Breaking this line down:

  • ${1-.} means use the first argument from the command line ($1) if it is available, otherwise use . which is a synonym for the current directory. Thus, the cd command either changes to the directory specified on the line that invoked dtree or to the current directory (a virtual no-op).

  • pwd then displays the path name of the current directory.

  • The parentheses around the whole line force the command to be run in a subshell. This means the cd command is local to this line and subsequent commands will be executed from what was the current directory when dtree was initially invoked.

  • The find command prints out all files whose type is d (for directory). The same directory reference is used as in cd.

  • The output of find is piped into find and the -f option tells sort to fold upper and lower case names together.

  • The tricky formatting of the tree is done by sed in four steps. Each step is set off by -e. This is how you tell sed a program follows.

  • The first expression, s,^${1-.},," is a substitute command which tells sed to replace everything between the first two delimiters (a comma is used as the delimiter) with everything between the second. The initial ^ causes the match to be performed only at the beginning of the line. The expression that follows is, again, the starting directory reference, and the string between the second pair of delimiters is null. Thus, the requested directory name from the beginning of the output of sort is trimmed.

  • The second expression, /^$/d tells sed to delete all blank lines (lines with nothing between the beginning and the end).

  • The third expression is probably the trickiest. It used the ability to remember a string within a regular expression and then use it later. The expression s,[^/]*/\([^/]*\)$,\`-----\1, tells sed to replace the last two strings separated by a slash (/) with a backquote, five dashes and the last string (following the final slash).

  • Lastly, the final expression, -e "s,[^/]*/,|      ,g" tells sed to replace every occurrence of strings that do not contain a slash but are followed by a slash, with a pipe (|) and six spaces.

Unless you are familiar with regular expressions you probably didn't follow all that. But you probably learned something and you can easily use dtree without having to understand how it works.

LJ Archive