2015-04-01 42 views
-1

我有一個程序,我正在嘗試寫一個需要一個非常大的目錄(裏面有10,000多個文件),並且會創建新的子目錄以將非常大的目錄分割成更小的塊(每個大約100個文件)。當我在終端中調用它時,我目前沒有提出任何錯誤,但它實際上沒有對大文件進行排序......我認爲問題與os.rename()相關,但我不理解爲什麼我也試過shutil.move()並且仍然有同樣的問題。對不起,我couldent使代碼出現在顏色我是新來的網站爲什麼os.rename程序沒有排序目錄

#!/usr/bin/python 
import os 
import glob 
import sys 
from functools import partial 
sys.setrecursionlimit(1000) 

def mk_osdict(a): 
    #os.chdir(a) 
    #grouping files with .mol2 endings only 
    os_list =glob.glob("*.mol2") 
    #making a dictionary for the list of files in the directory 
    os_dict = dict([i,n] for i,n in zip(range(len(os_list)),os_list)) 
    return os_dict 

dict_os = mk_osdict("decoys") 

#function to sort files into new directories with a specific size. 
def init_path(f): 
    block = (len(f)/100)+1 
    #i_lst gives a list of the number of entries 
    i_lst = [str(i) for i in range(block)] 
    '''paths keys will become new directories, values will be a list 
    files to be sorted into the corresponding directory''' 
    paths = dict(["decoydir"+n.zfill(5),[]] for n in i_lst) 
    for lst in paths.values(): 
     while len(lst) <= block: 
      for value in f.values(): 
       lst.append(value) 
    for x,p in paths: 
     if not os.path.exists(x): 
      os.mkdir(x) 
     else: 
      pass 
     for index in p: 
      yield os.rename(index,os.path.join(x,index)) 

b = init_path(dict_os) 
+0

你提到「,但它實際上並沒有排序的大型文件「;你的意思是'它不會從大目錄中刪除文件'?重命名不排序;它重命名文件,並且重命名的副作用可能是將單個文件從一個(大)目錄移動到一個(新的,小的)目錄中。如果您正在忙於在進程正在掃描時更改目錄的內容,但是它可能不會中斷,我還沒有探討過會發生什麼情況。 – 2015-04-01 16:06:17

+0

這不會有幾個原因,但是你的問題的一部分是'init_path'使用'yield'語句,它使得它成爲一個生成器。所以,只需調用它'b = init_path(dict_os)'(這也不起作用,因爲需要兩個參數)只是簡單地初始化生成器並且不執行任何重命名。 – tdelaney 2015-04-01 16:10:08

+0

@JonathanLeffler對此感到抱歉。我的意思是,當我運行程序時,沒有文件被分類到創建的新目錄中。 – 2015-04-01 18:09:52

回答

0

(借用d)可以更簡單地使用在返回的文件數列表操作執行此任務glob。創建中間數據結構使代碼更加混亂 - 你可以爲你去做的目錄中創建和移動:

進口OS 進口水珠

def mk_tree(path): 
    files = glob.glob(os.path.join(path, "*.mol2")) 
    chunks = [files[chunk:chunk+100] for chunk in range(0, len(files), 100)] 
    for i, chunk in enumerate(chunks): 
     new_dir = os.path.join(path, "decoydir%05d" % i) 
     os.mkdir(new_dir) 
     for fn in chunk: 
      os.rename(fn, os.path.join(new_dir, os.path.basename(fn))) 
+0

哇,這太棒了!非常感謝 :) – 2015-04-01 19:07:22

0

我的答案很可能不會告訴你什麼是你的代碼錯誤,但我認爲它會幫助你解決你最初的問題。 我相信這不是解決問題的最有效的方法,但它很容易測試,並且在我看來很好讀。

import os 

def read_dir(adir): 
    files = os.listdir(adir) 

    # do some filtering of files to get only the files you want 
    ... 

    return files 

# creates n amount of subdirs in a given dir 
# dirs get named 0,1,2,3... 
def create_subdirs(apath, n): 
    for i in n: 
     os.makedirs(apath+n) 

def move_files(myfiles, frm, to): 
    for fl in myfiles: 
     os.rename(frm+fl, to+fl) 

# yields chunks of a list of specific size 
def chunks(l, n): 
    """ Yield successive n-sized chunks from l. 
    """ 
    for i in xrange(0, len(l), n): 
     yield l[i:i+n] 

A_VERY_LARGE_DIR = "/path/to/dir/" 
files_in_large_dir = read_dir(A_VERY_LARGE_DIR) 
number_of_subdirs = (len(files_in_large_dir)/100)+1 
files_in_chunks = list(chunks(files_in_large_dir, 100)) 

create_subdirs(A_VERY_LARGE_DIR, number_of_subdirs) 

for i in number_of_subdirs: 
    topath = A_VERY_LARGE_DIR + i + "/" 
    move_files(files_in_chunks[i], A_VERY_LARGE_DIR, topath) 

注意:這不是完整的代碼。必須添加一些功能來過濾文件。路徑需要等來填充..

注2:本chunks功能我偷了:從this thread

+0

太棒了!所以這似乎工作,但你的發電機功能如何工作,但原來的不是?我使用了這個例子中的收益率,我在David Beazley的網站(dabeaze.com)上找到了進口os import fnmatch def gen_find(filepat,top): for path,dirlist,filelist in os.walk(top): 在fnmatch.filter(filelist,filepat)中: 產生os.path。加入(路徑,名稱) – 2015-04-01 17:58:07

+0

我認爲問題是,原始代碼產生os.rename只會產生該表達式,並不會執行它。在我的代碼中,我只是產生一個子列表。我可能是錯的:) – rfmind 2015-04-01 18:14:14

相關問題