我想创建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个代码段。问题是它只计算目录中的文件大小,因此结果大小小于目录的实际大小。其他问题是如何将所有内容组合在一起以打印上面定义的树而无需冗余计算。
答案 0 :(得分:4)
计算目录大小确实不是python的强项,如本文所述:very quickly getting total size of folder。如果您有权访问du
和find
,请务必使用该权限。您可以使用以下行轻松显示每个目录的大小:
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)