2012-03-15 25 views
42

Sé que podemos usar os.walk() para listar todos los subdirectorios o todos los archivos en un directorio. Sin embargo, me gustaría enumerar el contenido árbol de directorios completo:¿Estructura del árbol del directorio de la lista en python?

  • subdirectorio 1:
    • file11
    • file12
    • sub-sub-directorio 11:
      • file111
      • file112
  • subdirectorio 2:
    • file21
    • sub-sub-directorio de 21
    • sub-sub-directorio de 22
      • sub-sub-sub-directorio de archivos 221

¿Cómo lograr esto en Python?

+1

que sugeriría el uso de 'os.walk () ', pero parece que ya estás allí ... ¿qué has intentado? –

+0

Supongo que es porque no entiendo completamente la tupla. Sé cómo enumerar todos los directorios y todos los archivos por separado, pero no sé cómo enumerar los archivos y subdirectorios de un directorio sin superponer cosas. – user18115

+1

Ver la respuesta a [esta pregunta] (http://stackoverflow.com/questions/120656/directory-listing-in-python) –

Respuesta

69

Aquí es una función de hacer eso con el formato:

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

Esto funcionó muy bien , gracias. Aunque la mayoría sabría, aún para el beneficio de los recién llegados en python, tenga en cuenta que deberá llamar a la función al final (asumiendo windows), por lo que puede agregar una nueva línea al final con el contenido list_files ("D: \\ ") – Rahul

+0

Funcionó bien en python3. Pero en python2 se arroja 'ValueError: nombre de campo de longitud cero en formato '. – nipunasudha

+0

Hola dhobbs, traté de usar tu función. Me pregunto si hay alguna manera de devolver este árbol de directorios para recorrer el árbol de directorios desde el último hasta una carpeta determinada. Puedo publicar esto como una pregunta si quieres. –

16

Una solución sin su huella:

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

os.walk ya lo hace el de arriba hacia abajo, a pie primero en profundidad que busca.

Ignorar la lista de directorios evita la superposición que usted menciona.

+0

python dice: 'NameError: name 'path' no está definido' –

7

vine aquí en busca de lo mismo y se utiliza dhobbs respuesta para mí. Como una forma de agradecer a la comunidad, agregué algunos argumentos para escribir en un archivo, tal como lo pidió akshay, e hice que los archivos mostrados fueran opcionales por lo que no es tan difícil de obtener. También convirtió la sangría en un argumento opcional para que pueda cambiarla, ya que algunos prefieren que sea 2 y otros prefieren 4.

Se usaron diferentes bucles para que el que no muestra archivos no verifique si tiene que hacerlo en cada iteración.

Espero que ayude a alguien más ya que la respuesta de dhobbs me ayudó. Muchas gracias.

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

Creo que esta respuesta no contribuye a la respuesta ya aceptada. Lo único que está proporcionando es un código de pelusa adicional para desactivar las funciones o no en la respuesta. – CodeLikeBeaker

+1

Tu sensación es correcta, @ jason-heine. La respuesta aceptada es suficiente, pero algunas personas preguntaron cómo hacer estas cosas de pelusa y yo quería darles algo. Descálgalo o informa mi respuesta si no quieres ver esto en SO, pensé que no me haría daño, pero podría estar equivocado. –

+2

Es útil de hecho. Muchas gracias. Lo usé tal como es. – vladblindu

4

Sobre la base de esta fantástica posterior

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

Aquí it un refinamiento que se comporten exactamente igual

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

Encima de dhobbs respuesta anterior (https://stackoverflow.com/a/9728478/624597) , aquí hay un ex funcionalidad tra de almacenar los resultados en un archivo (Yo personalmente lo uso para copiar y pegar en FreeMind tener una buena visión general de la estructura, por lo tanto, utiliza pestañas en lugar de espacios para el sangrado):

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

Quizás más rápido que @ ellockie (Tal vez)

 
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("/") 

Editar: pantalla I se ensayó es que:

enter image description here

Cuestiones relacionadas