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

Вы упоминаете «, но это на самом деле не сортировать большой файл «; вы имеете в виду, что «он не удаляет файлы из большого каталога»? Переименование ничего не сортирует; он переименовывает файлы, а побочным эффектом переименования может быть перемещение отдельного файла из одного (большого) каталога в один (новый, маленький) каталог. Я не исследовал, что произойдет, если вы заняты изменением содержимого каталога во время сканирования процесса, но он, вероятно, не сломается. –

+0

Это не будет работать по нескольким причинам, но часть вашей проблемы состоит в том, что 'init_path' использует оператор' yield', который делает его генератором. Итак, просто называя его 'b = init_path (dict_os)' (который также не работает, потому что нужны два параметра) просто инициализирует генератор и не выполняет никаких переименований. – tdelaney

+0

@ JonathanLeffler извините за путаницу. Я имею в виду, что когда я запускаю программу, никакие файлы не сортируются в новые созданные каталоги. –

ответ

0

Вы можете выполнить эту задачу более просто используя несколько списков манипуляции с файлами, возвращенных 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))) 
+0

Ничего себе это здорово! Огромное спасибо :) –

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) 

Примечание: Это не полный код. Для фильтрации файлов необходимо добавить некоторую функциональность. Дорожки должны быть заполнены Etc ..

Примечание 2:. Функция chunks я украл (заимствовано: D) от this thread

+0

Отлично! так что это, похоже, работает, но почему ваша функция генератора работает, но в оригинале нет? Я использовал выход из этого примера, который я нашел на сайте Дэвида Безли (dabeaze.com) import os import fnmatch def gen_find (filepat, top): для пути, dirlist, filelist в os.walk (вверху): для имени в файле fnmatch.filter (filelist, filepat): выход os.path.join (путь, имя) –

+0

Я думаю, проблема в том, что исходный код дает os.rename, который просто дает это выражение и не выполняет его. В моем коде я просто получаю подсписок. Я мог ошибаться :) – rfmind

Смежные вопросы