2011-08-21 81 views
3

我想創建能夠打印目錄樹的大小爲所有子目錄(來自特定目錄)和最常見的擴展名的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

你有迄今爲止編寫任何代碼或映射出任何邏輯是什麼?請發佈。 – foosion

回答

4

計算目錄大小真的不是Python的強項,因爲在這個崗位解釋說:very quickly getting total size of folder。如果您有權訪問dufind,請務必使用該功能。您可以輕鬆地用下面一行顯示每個目錄的大小:

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

如果您在蟒蛇這樣堅持,你可能更post-order traversalos.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) 
-2

這就是您的need模塊。還有this

+0

這些將是最有用的模塊。 +1。也許要投入一個字典來跟蹤擴展和大小。 – foosion

+3

如果您只想將某人指向某個模塊,並且不說其他任何內容,請使用評論。如果你要回答,至少要指出他們的具體功能,或給他們一個想法如何弄清楚。 (我不是downvoter,我今天沒有投票,但我同意)。 – agf

+0

我指出這些模塊是因爲我認爲它們足夠好,文檔是不言自明的。也許你是對的,這會更適合作爲評論。然而,文檔說了一切,所以我不會改變我的答案。 – Marii

0

@Cldy是正確使用os.path中

例如os.path.walk會走路的深度先通過下面的參數每個目錄,並返回在每個目錄

使用os.path.getsize的文件和文件夾來獲取大小和拆分得到擴展。在列表或字典和存儲擴展通過每個

會後盡數如果您是在Linux上,我會在du建議找替代。

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) 
+0

謝謝你,你的代碼在Python中教會我好東西,我嘗試使用os.walk,但是它的使用非常複雜。你的遞歸看起來非常優雅。我試圖測試它,但它給了我[錯誤](http://pastebin.com/ytB9N7s1) – xralf

+0

我注意到它崩潰的目錄是符號鏈接。如果可能的話,可以避免符號鏈接。我現在正在Linux(Ubuntu)上測試它,但主要用法是在Windows 7上。 – xralf

相關問題