为什么 os.rename 程序没有对目录进行排序

Why is os.rename program not sorting directory

我有一个我正在尝试编写的程序,它将占用一个非常大的目录(里面有 10,000 多个文件),并将创建新的子目录以将非常大的目录分成更小的块(每个大约 100 个文件) .当我在终端中调用它时,我目前拥有的程序没有引发任何错误,但它实际上并没有对大文件进行排序......我认为问题出在 os.rename() 但我不明白为什么我也试过shutil.move() 仍然有同样的问题。抱歉,我无法让代码以彩色显示我是该网站的新手

#!/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 )

我的回答可能不会告诉您代码有什么问题,但我认为它会帮助您解决最初的问题。 我确信这不是解决它的最有效方法,但它很容易测试,而且在我看来可读性很好。

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

窃取(借用 :D )

您可以通过对 glob 返回的文件进行一些列表操作来更简单地执行此任务。创建中间数据结构会使代码更加混乱 - 您可以只创建目录并随手移动:

进口os 导入 glob

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