2012-03-15 7 views
42

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

  • подкаталог 1:
    • file11
    • file12
    • Sub-подкаталог 11:
      • file111
      • file112
  • Подкаталог 2:
    • file21
    • суб-суб-каталог 21
    • суб-суб-каталог 22
      • суб-суб-суб-каталог 221
        • файл 2211

Как добиться этого в Python?

+1

Я предложил бы использовать 'os.walk () ', но похоже, что вы уже там ... что вы пробовали? –

+0

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

+1

См. Ответ на [этот вопрос] (http://stackoverflow.com/questions/120656/directory-listing-in-python) –

ответ

69

Вот функция, чтобы сделать это с форматированием:

import os 

def list_files(startpath): 
    for root, dirs, files in os.walk(startpath): 
     level = root.replace(startpath, '').count(os.sep) 
     indent = ' ' * 4 * (level) 
     print('{}{}/'.format(indent, os.path.basename(root))) 
     subindent = ' ' * 4 * (level + 1) 
     for f in files: 
      print('{}{}'.format(subindent, f)) 
+1

Это работало очень хорошо , Спасибо. Хотя большинство из них будет знать, что все еще для новичков в python - обратите внимание, что вам нужно будет вызвать функцию в конце (предполагая окна), поэтому вы можете добавить новую строку в конец с содержимым list_files («D: \\ ") – Rahul

+0

Хорошо работает на python3. Но на python2 «ValueError: имя поля нулевой длины в формате» бросается. – nipunasudha

+0

Привет, дхоббс, я попытался использовать вашу функцию. Интересно, есть ли способ вернуть это дерево каталогов, чтобы перебирать дерево каталогов из последней в определенную папку! Я могу опубликовать это как вопрос, если хотите. –

16

раствор без вашего отпечатка:

for path, dirs, files in os.walk(path): 
    print path 
    for f in files: 
    print f 

os.walk уже делает сверху вниз, в глубину ходьбы вы ищете.

Игнорирование списка dirs предотвращает дублирование, о котором вы упоминаете.

+0

python говорит: 'NameError: name 'path' не определен' –

7

Я пришел сюда в поисках того же и используется dhobbs ответ для меня. Как способ поблагодарить сообщество, я добавил несколько аргументов для записи в файл, как сказал akshay, и сделал показ файлов необязательным, так что это не так бит вывода. Также сделал отступ дополнительным аргументом, чтобы вы могли его изменить, так как некоторые из них должны быть равны 2 и другие. 4.

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

Надеюсь, что это поможет кому-то другому, поскольку ответ дхоббс мне помог. Большое спасибо.

def showFolderTree(path,show_files=False,indentation=2,file_output=False): 
""" 
Shows the content of a folder in a tree structure. 
path -(string)- path of the root folder we want to show. 
show_files -(boolean)- Whether or not we want to see files listed. 
         Defaults to False. 
indentation -(int)- Indentation we want to use, defaults to 2. 
file_output -(string)- Path (including the name) of the file where we want 
         to save the tree. 
""" 


tree = [] 

if not show_files: 
    for root, dirs, files in os.walk(path): 
     level = root.replace(path, '').count(os.sep) 
     indent = ' '*indentation*(level) 
     tree.append('{}{}/'.format(indent,os.path.basename(root))) 

if show_files: 
    for root, dirs, files in os.walk(path): 
     level = root.replace(path, '').count(os.sep) 
     indent = ' '*indentation*(level) 
     tree.append('{}{}/'.format(indent,os.path.basename(root)))  
     for f in files: 
      subindent=' ' * indentation * (level+1) 
      tree.append('{}{}'.format(subindent,f)) 

if file_output: 
    output_file = open(file_output,'w') 
    for line in tree: 
     output_file.write(line) 
     output_file.write('\n') 
else: 
    # Default behaviour: print on screen. 
    for line in tree: 
     print line 
+0

Я чувствую, что этот ответ не способствует принятию уже принятого ответа. Единственное, что вы предоставляете, это дополнительный пушистый код, чтобы отключить функции или нет в ответе. – CodeLikeBeaker

+1

Ваше чувство правильно, @ jason-heine. Принятый ответ достаточно хорош, но некоторые люди спрашивали, как это сделать, и я хотел что-то им дать. Снизьте это или сообщите мой ответ, если вы не хотите видеть это в SO, я думал, что это не повредит, но я могу ошибаться. –

+2

Это действительно полезно. Большое спасибо. Я использовал его как есть. – vladblindu

4

Основываясь на этом фантастическом пост

http://code.activestate.com/recipes/217212-treepy-graphically-displays-the-directory-structur/

Здесь эс уточнение, чтобы вести себя так же, как

http://linux.die.net/man/1/tree

 
#!/usr/bin/env python2 
# -*- coding: utf-8 -*- 

# tree.py 
# 
# Written by Doug Dahms 
# 
# Prints the tree structure for the path specified on the command line 

from os import listdir, sep 
from os.path import abspath, basename, isdir 
from sys import argv 

def tree(dir, padding, print_files=False, isLast=False, isFirst=False): 
    if isFirst: 
     print padding.decode('utf8')[:-1].encode('utf8') + dir 
    else: 
     if isLast: 
      print padding.decode('utf8')[:-1].encode('utf8') + '└── ' + basename(abspath(dir)) 
     else: 
      print padding.decode('utf8')[:-1].encode('utf8') + '├── ' + basename(abspath(dir)) 
    files = [] 
    if print_files: 
     files = listdir(dir) 
    else: 
     files = [x for x in listdir(dir) if isdir(dir + sep + x)] 
    if not isFirst: 
     padding = padding + ' ' 
    files = sorted(files, key=lambda s: s.lower()) 
    count = 0 
    last = len(files) - 1 
    for i, file in enumerate(files): 
     count += 1 
     path = dir + sep + file 
     isLast = i == last 
     if isdir(path): 
      if count == len(files): 
       if isFirst: 
        tree(path, padding, print_files, isLast, False) 
       else: 
        tree(path, padding + ' ', print_files, isLast, False) 
      else: 
       tree(path, padding + '│', print_files, isLast, False) 
     else: 
      if isLast: 
       print padding + '└── ' + file 
      else: 
       print padding + '├── ' + file 

def usage(): 
    return '''Usage: %s [-f] 
Print tree structure of path specified. 
Options: 
-f  Print files as well as directories 
PATH Path to process''' % basename(argv[0]) 

def main(): 
    if len(argv) == 1: 
     print usage() 
    elif len(argv) == 2: 
     # print just directories 
     path = argv[1] 
     if isdir(path): 
      tree(path, '', False, False, True) 
     else: 
      print 'ERROR: \'' + path + '\' is not a directory' 
    elif len(argv) == 3 and argv[1] == '-f': 
     # print directories and files 
     path = argv[2] 
     if isdir(path): 
      tree(path, '', True, False, True) 
     else: 
      print 'ERROR: \'' + path + '\' is not a directory' 
    else: 
     print usage() 

if __name__ == '__main__': 
    main() 


0

На вершине dhobbs ответ выше (https://stackoverflow.com/a/9728478/624597) , здесь есть Функциональность тра хранения результатов в файл (я лично использую его, чтобы скопировать и вставить в FreeMind иметь хороший обзор структуры, поэтому я использовал вкладки вместо пространства для отступа):

import os 

def list_files(startpath): 

    with open("folder_structure.txt", "w") as f_output: 
     for root, dirs, files in os.walk(startpath): 
      level = root.replace(startpath, '').count(os.sep) 
      indent = '\t' * 1 * (level) 
      output_string = '{}{}/'.format(indent, os.path.basename(root)) 
      print(output_string) 
      f_output.write(output_string + '\n') 
      subindent = '\t' * 1 * (level + 1) 
      for f in files: 
       output_string = '{}{}'.format(subindent, f) 
       print(output_string) 
       f_output.write(output_string + '\n') 

list_files(".") 
0

Может быть быстрее, чем @ ellockie (Может быть)

 
import os 
def file_writer(text): 
    with open("folder_structure.txt","a") as f_output: 
     f_output.write(text) 
def list_files(startpath): 


    for root, dirs, files in os.walk(startpath): 
     level = root.replace(startpath, '').count(os.sep) 
     indent = '\t' * 1 * (level) 
     output_string = '{}{}/ \n'.format(indent, os.path.basename(root)) 
     file_writer(output_string) 
     subindent = '\t' * 1 * (level + 1) 
     output_string = '%s %s \n' %(subindent,[f for f in files]) 
     file_writer(''.join(output_string)) 


list_files("/") 

Edit: Я был испытан скриншот, что:

enter image description here

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