2016-08-30 2 views
0

У меня есть сценарий, который будет перечислять все папки и подпапки и создать файл JSON. То, что я пытаюсь сделать, это только папки, содержащие подпапки с именем «Карты» или «Отчеты». Если они содержат их, тогда будет указана только родительская папка, поэтому «Карты», «Отчеты» не будут показаны. В настоящее время застрял на том, как это сделать, любая помощь будет отличной.Python список только папки, которые содержат определенные подпапки

import os, json, sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 
path = "G:\Testfolders" 

def get_list_of_dirs(path): 

    try: 
     output_dictonary = {} 
     list_of_dirs = [os.path.join(path, item) for item in os.listdir(path) if os.path.isdir(os.path.join(path, item)) and os.path.isdir("./Maps") and os.path.isdir("./Reports")] 

     output_dictonary["text"] = path.decode('latin1') 
     output_dictonary["type"] = "directory" 
     output_dictonary["children"] = [] 
     for dir in list_of_dirs: 
     output_dictonary["children"].append(get_list_of_dirs(dir)) 
     return output_dictonary 
    except WindowsError: 
     pass 

    print json.dumps(get_list_of_dirs(path)) 

with open(r'U:\JSONDatatest.json', 'w') as f: 
    json.dump(get_list_of_dirs(path), f) 

Отредактировано:

import os, json, sys 

def all_dirs_with_subdirs(path,subdirs): 
    # make sure no relative paths are returned, can be omitted 
    try: 
     output_dictonary = {} 

     path = os.path.abspath(path) 

     list_of_dirs = [] 
     for root, dirs, files in os.walk(path): 
      if all(subdir in dirs for subdir in subdirs): 
        list_of_dirs.append(root) 
     return list_of_dirs 
     output_dictonary["text"] = path.decode('latin1') 
     output_dictonary["type"] = "directory" 

     output_dictonary["children"] = [] 
     for dir in list_of_dirs: 
      output_dictonary["children"].append(all_dirs_with_subdirs(dir)) 
     return output_dictonary 
    except WindowsError: 
     pass 

with open(r'U:\jsontesting\JSONData.json', 'w') as f: 
    json.dump(all_dirs_with_subdirs("G:\TESTPATH", ('Maps', 'Temp')), f) 

ответ

0

Я думаю, что вы ищете команду os.walk, я реализовал функцию, используя его ниже. (Также сделал это немного более общий)

import os 

# path : string to relative or absolute path to be queried 
# subdirs: tuple or list containing all names of subfolders that need to be 
#   present in the directory 
def all_dirs_with_subdirs(path, subdirs): 
    # make sure no relative paths are returned, can be omitted 
    path = os.path.abspath(path) 

    result = [] 
    for root, dirs, files in os.walk(path): 
     if all(subdir in dirs for subdir in subdirs): 
       result.append(root) 
    return result 

def get_directory_listing(path): 
    output = {} 
    output["text"] = path.decode('latin1') 
    output["type"] = "directory" 
    output["children"] = all_dirs_with_subdirs(path, ('Maps', 'Reports')) 
    return output 

with open('test.json', 'w+') as f: 
    listing = get_directory_listing(".") 
    json.dump(listing, f) 

UPDATE: Также JSON материал

+0

P.S. Я знаю, что я не упомянул о json, я понял, что кодировка массива символов юникода в json на самом деле не проблема, так как эта часть должна работать atm. –

+0

Спасибо, что работает отлично. Однако у JSON возникают проблемы с поиском родительского/дочернего дерева этого выходного списка. Я попытался использовать это, чтобы преобразовать с помощью json, но он просто выплевывает список папок без родителя и т. Д. Я добавил его к моему вопросу. – Infinity8

+0

Awesome. Папки дочерних дочерних элементов все сгруппированы как дочерние папки с нижним уровнем вниз. Например, G: \ TEST \ a \ b \ находится на том же уровне, что и G: \ TEST \ a \. Есть ли способ сохранить свою первоначальную структуру? – Infinity8

0

Если вы хотели бы использовать Glob:

def get_list_of_dirs(): 

    from glob import glob 
    import os.path as path 

    # get the directories containing Maps 
    maps = set([path.abspath(path.join(f + path.pardir)) 
       for f in glob('**/Maps/')]) 
    # get the directories containing Reports 
    reports = set([path.abspath(path.join(f + path.pardir)) 
         for f in glob('**/Reports/')]) 
    # return the common ones 
    return maps.intersection(reports) 

Вы можете сделать его более универсальным путем пропускания список выражений glob для функции, а затем возвращение пересечения множеств или пересекающихся по ходу.

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