Mimicking Linux Tree Utility

Introduction

Many blogs are showing how to print directory tree using Python. Drawing from those examples, we built our version. The primary drivers were:

  1. Compatibility with Python3
  2. Print symbolic links
  3. Limit depth of tree

Example output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ ptree.py -l 2 /var

var -> private/var/
|-- venv -> /usr/local/share/virtualenvs
|-- accord/
|   |-- .DS_Store
|   |-- data/
|   |   |-- .DS_Store
|-- acrisel/
|   |-- .DS_Store
|   |-- .gitignore
|   |-- accord/
|   |   |-- .DS_Store

Function Code

 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
import os

def realname(path, root=None):
    if root is not None:
        path=os.path.join(root, path)
    result=os.path.basename(path)
    if os.path.islink(path):
        realpath=os.readlink(path)
        result= '%s -> %s' % (os.path.basename(path), realpath)
    return result

def ptree(startpath, depth=-1):
    prefix=0
    if startpath != '/':
        if startpath.endswith('/'): startpath=startpath[:-1]
        prefix=len(startpath)
    for root, dirs, files in os.walk(startpath):
        level = root[prefix:].count(os.sep)
        if depth >-1 and level > depth: continue
        indent=subindent =''
        if level > 0:
            indent = '|   ' * (level-1) + '|-- '
        subindent = '|   ' * (level) + '|-- '
        print('{}{}/'.format(indent, realname(root)))
        # print dir only if symbolic link; otherwise, will be printed as root
        for d in dirs:
            if os.path.islink(os.path.join(root, d)):
                print('{}{}'.format(subindent, realname(d, root=root)))
        for f in files:
            print('{}{}'.format(subindent, realname(f, root=root)))

I will refrain from going over the code, otherwise self-explanatory, except mentioning the following:

  1. os.walk treats symbolic links per their target. Therefore, a symbolic link may appear in dirs and files.
  2. only two main features of tree are replicated: accepting both a root path and depth to explore.

Command line Arguments

Command line arguments is simple and self explanatory ...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='prints directory tree.')
    parser.add_argument('--level', '-l', type=int, dest='depth', default=-1,
                        help='depth of tree to print')
    parser.add_argument('startpath', type=str,
                        help='path to stating directory')
    args = parser.parse_args()
    argsd=vars(args)
    ptree(**argsd)

References

ptree.py can be download from github

Give us your feedback: support@acrisel.com
Visit us at our home

Share Post:

LinkedinDiaspora*TwitterFacebookGoogle+Email

Comments


There are no comments yet.

Add a Comment

You can use the Markdown syntax to format your comment.