ActiveState Code

Recipe 217212: tree.py - graphically displays the directory structure of a specified path


The following program displays the directory structure of a specified path using ASCII characters. The program can optionally display files in addition to directories. This program functions similar to the windows 'tree' command.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#! /usr/bin/env python

# tree.py
#
# Written by Doug Dahms
#
# Prints the tree structure for the path specified on the command line

from os import listdir, sep
from os.path import abspath, basename, isdir
from sys import argv

def tree(dir, padding, print_files=False):
    print padding[:-1] + '+-' + basename(abspath(dir)) + '/'
    padding = padding + ' '
    files = []
    if print_files:
        files = listdir(dir)
    else:
        files = [x for x in listdir(dir) if isdir(dir + sep + x)]
    count = 0
    for file in files:
        count += 1
        print padding + '|'
        path = dir + sep + file
        if isdir(path):
            if count == len(files):
                tree(path, padding + ' ', print_files)
            else:
                tree(path, padding + '|', print_files)
        else:
            print padding + '+-' + file

def usage():
    return '''Usage: %s [-f] <PATH>
Print tree structure of path specified.
Options:
-f      Print files as well as directories
PATH    Path to process''' % basename(argv[0])

def main():
    if len(argv) == 1:
        print usage()
    elif len(argv) == 2:
        # print just directories
        path = argv[1]
        if isdir(path):
            tree(path, ' ')
        else:
            print 'ERROR: \'' + path + '\' is not a directory'
    elif len(argv) == 3 and argv[1] == '-f':
        # print directories and files
        path = argv[2]
        if isdir(path):
            tree(path, ' ', True)
        else:
            print 'ERROR: \'' + path + '\' is not a directory'
    else:
        print usage()

if __name__ == '__main__':
    main()

Discussion

For some of the projects I have worked on it is necessary to document the directory [and file] structure of a specified path. Manually creating a ASCII tree representation is laborious. In the windows world there exists the 'tree' command to handle this task. However in the Linux/Unix world I was not aware of an equivalent command. Thus I created this program.

Comments

  1. 1. At 1:14 a.m. on 25 aug 2003, Keith Dart said:

    There is a utility.... FYI:

    rpm -qi tree-1.2-7mdk
    
    Name        : tree                         Relocations: /usr
    Version     : 1.2                               Vendor: (none)
    Release     : 7mdk                          Build Date: Wed May  5 14:05:49 1999Install date: Fri Nov  5 05:54:15 1999      Build Host: http://k6.microsoft.sucks.eu.org
    Group       : Applications/File             Source RPM: tree-1.2-7mdk.src.rpm
    Size        : 21607                            License: GPL
    Summary     : A utility which displays a tree view of the contents of directories.
    Description :
    The tree utility recursively displays the contents of directories in a
    tree-like format.  Tree is basically a UNIX port of the tree DOS
    utility.
    
    Install tree if you think it would be useful to view the contents of
    specified directories in a tree-like format.
    
  2. 2. At 4:08 p.m. on 29 aug 2003, Doug Dahms (the author) said:

    Thanks... Oh darn. Looks like I did it again... reinventing the wheel. ;) Thanks for the info Keith.

  3. 3. At 9:59 a.m. on 2 sep 2003, Dinu Gherman said:

    More concise output and code. I find the following more concise (where find is available...).

    def tree(dir, padding, print_files=False):
        cmd = "find '%s'" % dir
        files = os.popen(cmd).read().strip().split('\n')
        padding = '|  '
        for file in files:
            level = file.count(os.sep)
            pieces = file.split(os.sep)
            symbol = {0:'', 1:'/'}[isdir(file)]
            if not print_files and symbol != '/':
                continue
            print padding*level + pieces[-1] + symbol
    
  4. 4. At 7 a.m. on 29 mar 2008, Lance Miller said:

    No success.

    >./tree.py -help
    : No such file or directory
    >./tree.py
    : No such file or directory
    >./tree.py .
    : No such file or directory
    >./tree.py /Applications
    : No such file or directory
    >./tree.py `pwd`
    : No such file or directory
    >./tree.py pwd
    : No such file or directory
    >./tree.py ~/
    : No such file or directory
    >./tree.py -f `pwd`
    : No such file or directory
    >
    

Sign in to comment