2015-04-01 49 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