目录大小和扩展名

时间:2011-08-21 12:51:50

标签: python directory file-extension

我想创建python命令行代码,它能够打印所有子目录(来自某个目录)和最常见扩展名的目录树...我将显示示例输出。

  
      
  • root_dir(5 GB,jpg(65%):avi(30%):pdf(5%))
  •   
     

- aa(3 GB,jpg(100%))

     

- bb(2 GB,avi(20%):pdf(2%))

     

--- bbb(1 GB,...)

     

--- bb2(1 GB,...)

     

- cc(1 GB,pdf(100%))

格式为:

嵌套级别,目录名称(包含所有文件和子目录的目录的大小,此目录中包含大小百分比的最常用扩展名。

到目前为止,我有this个代码段。问题是它只计算目录中的文件大小,因此结果大小小于目录的实际大小。其他问题是如何将所有内容组合在一起以打印上面定义的树而无需冗余计算。

4 个答案:

答案 0 :(得分:4)

计算目录大小确实不是python的强项,如本文所述:very quickly getting total size of folder。如果您有权访问dufind,请务必使用该权限。您可以使用以下行轻松显示每个目录的大小:

find . -type d -exec du -hs "{}" \;

如果你坚持在python中这样做,你可能更喜欢post-order traversal而非os.walk,正如PableG所建议的那样。但如果效率不是最重要的因素,那么使用os.walk可以在视觉上更清晰:

import os, sys
from collections import defaultdict

def walkIt(folder):
    for (path, dirs, files) in os.walk(folder):
        size = getDirSize(path)
        stats = getExtensionStats(files)

        # only get the top 3 extensions
        print '%s (%s, %s)'%(path, size, stats[:3])

def getExtensionStats(files):
    # get all file extensions
    extensions = [f.rsplit(os.extsep, 1)[-1] 
        for f in files if len(f.rsplit(os.extsep, 1)) > 1]

    # count the extensions
    exCounter = defaultdict(int)
    for e in extensions:
        exCounter[e] += 1

    # convert count to percentage
    percentPairs = [(e, 100*ct/len(extensions)) for e, ct in exCounter.items()]

    # sort them
    percentPairs.sort(key=lambda i: i[1])
    return percentPairs

def getDirSize(root):
    size = 0
    for path, dirs, files in os.walk(root):
        for f in files:
            size +=  os.path.getsize( os.path.join( path, f ) )
    return size

if __name__ == '__main__':
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    walkIt(path)

答案 1 :(得分:2)

我个人觉得os.listdir + a_recursive_function最适合这个任务而不是os.walk:

import os, copy
from os.path import join, getsize, isdir, splitext

frequent_ext = { ".jpg": 0, ".pdf": 0 }     # Frequent extensions

def list_dir(base_dir):
    dir_sz = 0  # directory size
    files = os.listdir(base_dir)
    ext_size = copy.copy(frequent_ext)

    for file_ in files:
        file_ = join(base_dir, file_)

        if isdir(file_):
            ret = list_dir(file_)
            dir_sz += ret[0]
            for k, v in frequent_ext.items():           # Add to freq.ext.sizes
                ext_size[k] += ret[1][k]
        else:
            file_sz = getsize(file_)
            dir_sz += file_sz

            ext = os.path.splitext(file_)[1].lower()   # Frequent extension?
            if ext in frequent_ext.keys():
                ext_size[ext] += file_sz

    print base_dir, dir_sz,
    for k, v in ext_size.items():
        print "%s: %5.2f%%" % (k, float(v) / max(1, dir_sz) * 100.),

    print 

    return (dir_sz, ext_size)


base_dir = "e:/test_dir/"
base_dir = os.path.abspath(base_dir)
list_dir(base_dir)

答案 2 :(得分:0)

@Cldy正确使用os.path

例如os.path.walk将首先遍历参数下面的每个目录,并返回每个目录中的文件和文件夹

使用os.path.getsize获取尺寸并拆分以获取扩展程序。将扩展名存储在列表或词典中,并在完成每个

后对其进行计数

如果您使用的是Linux,我建议您改为du

答案 3 :(得分:-2)

那是你need的模块。还有this