python-treeディスクサイズ表示-運維利器

8729 ワード

      ,      du -sh *   cd          ,       。
        ,      python   tree,        
      tree   ,             ,                ~~
#! /usr/bin/env python 
# -*- coding: gbk -*-

'''
@note     :   tree some path and display the leaf folder size by order
@authors  :   U{peterguo<mailto: [email protected]>}
@copyright:   tencent
@date     :   2013-02-25
@version  :   1.0.0.1
'''


import os
import sys
from optparse import OptionParser


def dumplog(aStr, strMod="a"):
    fp = file('run.log', strMod)
    fp.write(str(aStr) + "
")     fp.close() def get_prefix(fs):     u'''get display tags according dir path     '''     s = ''     for i in range(0,len(fs)):         last = (i == len(fs)-1)         if fs[i] and last:             s = s + '|-'         elif fs[i] and not last:             s = s + '| '         elif not fs[i] and last:             s = s + '.-'         else:             s = s + '  '              if i != len(fs)-1:             s = s + ' '         else:             s = s + '-'     return s      def print_tree(current,fs,if_size,if_nofile):     u'''recurise display dirs     '''     global d_count,f_count,size,d_file2size,d_dir2size     fs.append(True)     dirs = []     try:         dirs = os.listdir(current)     except:         print "Exception on listdir [%s], ignore ......" % current             for i in range(0,len(dirs)):         if os.path.islink(current+os.sep+dirs[i]):             continue         abs_file = os.path.realpath(current+os.sep+dirs[i])                  if i == len(dirs)-1:             fs[len(fs)-1] = False         if fs[len(fs)-1] and if_nofile:             last_flag = True             for j in range(i+1,len(dirs)):                 if os.path.isdir(os.path.realpath(current+os.sep+dirs[j])):                     last_flag = False                     break             if last_flag:                 fs[len(fs)-1] = False                        if os.path.isdir(abs_file):             print '%s%s' % (get_prefix(fs),dirs[i])             dumplog('%s%s' % (get_prefix(fs),dirs[i]))             if not d_dir2size.has_key(abs_file):                 d_dir2size[abs_file] = 0;             d_count = d_count + 1             print_tree(abs_file,fs[:],if_size,if_nofile)         else:             try:                 file_size = os.path.getsize(abs_file)                      d_file2size[abs_file] = file_size                 if if_size:                     size = size + file_size                  if not if_nofile:                     print '%s%s' % (get_prefix(fs),dirs[i])                     dumplog('%s%s' % (get_prefix(fs),dirs[i]))                  f_count = f_count + 1             except:                 pass              def print_total(dir_count,file_count,if_size=False,file_size=0):     u'''print summary information     '''     if not if_size:         print u'total %d folder,%d files' % (d_count,f_count)         dumplog('total %d folder,%d files' % (d_count,f_count))     else:         unit = ('B','KB','MB','GB','TB')         i = len(str(size))/3         if i > 4:             i = 4         unit_size = 1024 ** i         f_size = round(float(size)/unit_size,2)         print u' total %d folders,%d files, size %s %s' % (d_count,f_count,f_size,unit[i])         dumplog(' total %d folders,%d files, size %s %s' % (d_count,f_count,f_size,unit[i]))     print ''     dumplog('') parser = OptionParser() parser.add_option("-p", "--paths",  dest="paths",  help="path") parser.add_option("-s", "--size",   dest="size",   action="store_true", default=False, help="size the result") parser.add_option("-f", "--nofile", dest="nofile", action="store_true", default=False, help="ignore file") f_count = 0 d_count = 0 size = 0 d_dir2size = {}             #record dir size d_file2size = {}           #record file size      if __name__ == "__main__":     options, args = parser.parse_args()     dumplog("start .......", 'wt')     if len(args)==0 :         print u'can not find target path, default as current path'         print os.getcwd()         d_dir2size[os.getcwd()] = 0         print_tree(os.getcwd(),[],options.size==True,options.nofile==True)         print_total(d_count,f_count,options.size==True,size)     else:         for path in args:             f_count = 0             d_count = 0             size = 0             if not os.path.exists(path):                             print u'skip',path,u', can not find path.'                 print ''                 continue             path = os.path.realpath(path)             d_dir2size[path] = 0             print path             print_tree(os.path.normpath(path),[],options.size==True,options.nofile==True)             print_total(d_count,f_count,options.size==True,size)     #******************** summary every leaf folder *****************************#     for afile in d_file2size.keys():         d_dir2size[os.path.dirname(afile)] += d_file2size[afile]     l_out = []     for key in d_dir2size.keys():         if d_dir2size[key] != 0:             l_out.append("%10.4f MBytes \t%s" % (d_dir2size[key]/(1024*1024.0), key))     l_out.sort()          for item in l_out:         print item         dumplog(str(item))

出力例:
python mytree.py -f /usr/local/apache2/
/usr/local/apache2
|--lib
|  .--pkgconfig
|--bin
|--build
|--include
|--modules
|--conf
|  |--extra
|  |--original
|  |  .--extra
|  .--soso.d
|--htdocs
|--error
|  .--include
|--icons
|  .--small
|--logs
|--cgi-bin
|--man
|  |--man1
|  .--man8
.--manual
   |--developer
   |--faq
   |--howto
   |--images
   |--misc
   |--mod
   |--platform
   |--rewrite
   |--ssl
   |--style
   |  |--css
   |  |--lang
   |  |--latex
   |  .--xsl
   |     .--util
   |--programs
   .--vhosts
total 39 folder,1212 files

    0.0000 MBytes       /usr/local/apache2/htdocs
    0.0004 MBytes       /usr/local/apache2/conf/soso.d
    0.0007 MBytes       /usr/local/apache2/lib/pkgconfig
    0.0010 MBytes       /usr/local/apache2/cgi-bin
    0.0013 MBytes       /usr/local/apache2/error/include
    0.0025 MBytes       /usr/local/apache2/manual/style/latex
    0.0125 MBytes       /usr/local/apache2/manual/style
    0.0127 MBytes       /usr/local/apache2/conf/original
    0.0140 MBytes       /usr/local/apache2/manual/faq
    0.0154 MBytes       /usr/local/apache2/icons/small
    0.0210 MBytes       /usr/local/apache2/man/man1
    0.0311 MBytes       /usr/local/apache2/conf/extra
    0.0311 MBytes       /usr/local/apache2/conf/original/extra
    0.0350 MBytes       /usr/local/apache2/man/man8
    0.0359 MBytes       /usr/local/apache2/manual/style/css
    0.0946 MBytes       /usr/local/apache2/conf
    0.1082 MBytes       /usr/local/apache2/icons
    0.1192 MBytes       /usr/local/apache2/manual/images
    0.1323 MBytes       /usr/local/apache2/manual/rewrite
    0.1482 MBytes       /usr/local/apache2/error
    0.1569 MBytes       /usr/local/apache2/manual/developer
    0.1682 MBytes       /usr/local/apache2/manual/ssl
    0.2167 MBytes       /usr/local/apache2/manual/platform
    0.2469 MBytes       /usr/local/apache2/build
    0.3739 MBytes       /usr/local/apache2/manual/misc
    0.3900 MBytes       /usr/local/apache2/manual/howto
    0.5180 MBytes       /usr/local/apache2/manual/vhosts
    0.5301 MBytes       /usr/local/apache2/manual/programs
    1.1219 MBytes       /usr/local/apache2/include
    2.3524 MBytes       /usr/local/apache2/manual
    2.6087 MBytes       /usr/local/apache2/bin
    3.1963 MBytes       /usr/local/apache2/lib
    5.3836 MBytes       /usr/local/apache2/manual/mod
   25.7610 MBytes       /usr/local/apache2/modules
   94.4569 MBytes       /usr/local/apache2/logs

参照先:http://qingyi.iteye.com/blog/1325347
付録:サブディレクトリとサブファイルを巡回する
def recursive_dir(strPath, strType="file"): 
    lRet = []    
    list_dirs = os.walk(strPath)
    for root, dirs, files in list_dirs: 
        for d in dirs:
            if strType in ("dir", "all"):
                lRet.append(os.path.join(root, d))
        for f in files: 
            if strType in ("file","all"):
                lRet.append(os.path.join(root, f))
    return lRet