Small `du' reformatter :-)

François Pinard pinard at iro.umontreal.ca
Sun Jan 23 10:55:26 EST 2000


Derek Moeller <moeller at networksplus.net> écrit:

> I must say, [the `dutree' script] is quite a bit nicer. Requires most
> recent version of python, I believe, but considering that it would ship
> with it it's not a problem.

Thanks, Derek.  By the way, I needed and added options to prune the tree
either from nodes being too deep (past a certain level) or too small
(below a threshold size).  It makes the script a bit bigger, but not to
the point of ugliness, I think.  Here is the updated version.

-------------- next part --------------
#!/usr/bin/python
# Produce directory hierarchy with sizes, well sorted and indented.
# Copyright © 1996, 1999, 2000 Progiciels Bourbeau-Pinard inc.
# François Pinard <pinard at iro.umontreal.ca>, 1996.

# Idea from Pierre Rioux <riouxp at bch.umontreal.ca>, 1996-07-12.

"""\
Usage: tree [-l LEVEL] [-s SIZE] [PATH]...

  -l LEVEL    disregard directories more than LEVEL levels deep
  -s SIZE     disregard directories smaller than SIZE Kb
"""

import getopt, os, string, sys

def main(*arguments):
    # Decode options.
    level_option = size_option = None
    options, arguments = getopt.getopt(arguments, 'l:s:')
    for option, value in options:
        if option == '-l':
            level_option = int(value)
        elif option == '-s':
            size_option = int(value)
    # Get data properly sorted.
    items = map(presort,
                os.popen('du %s' % string.join(arguments)).readlines())
    items.sort()
    items = map(postsort, items)
    # Filter the results.
    if level_option or size_option:
        new_items = []
        for item in items:
            split, size = item
            if not level_option or len(split) <= level_option:
                if not size_option or size >= size_option:
                    new_items.append(item)
        items = new_items
    # Erase unneeded fragments of vertical lines.
    clean(items)
    items.reverse()
    clean(items)
    items.reverse()
    # Erase leftmost white columns.
    skip = 0
    split, size = items[0]
    while not split[skip]:
        skip = skip + 1
    # Produce display.
    for split, size in items:
        sys.stdout.write('%7d ' % size)
        for item in split[skip:-1]:
            if item:
                sys.stdout.write('|  ')
            else:
                sys.stdout.write('   ')
        sys.stdout.write('\\_ %s' % split[-1])

def presort(line):
    size, path = string.split(line, '\t')
    return path, int(size)

def postsort((path, size)):
    return string.split(path, '/'), size

def clean(items):
    # The basename is always written.  Intermediate directories
    # normally print as `|', yet None is used to inhibit the line.
    draw = []
    for split, size in items:
        while len(draw) > len(split) - 1:
            draw.pop()
        while len(draw) < len(split) - 1:
            draw.append(0)
        draw.append(1)
        for counter in range(len(split) - 1):
            if not draw[counter]:
                split[counter] = None

if __name__ == '__main__':
    apply(main, sys.argv[1:])
-------------- next part --------------

-- 
François Pinard   http://www.iro.umontreal.ca/~pinard


More information about the Python-list mailing list