Elenca la struttura ad albero delle directory in Python?


111

So che possiamo usare os.walk()per elencare tutte le sottodirectory o tutti i file in una directory. Tuttavia, vorrei elencare l'intero contenuto dell'albero delle directory:

- Subdirectory 1:
   - file11
   - file12
   - Sub-sub-directory 11:
         - file111
         - file112
- Subdirectory 2:
    - file21
    - sub-sub-directory 21
    - sub-sub-directory 22    
        - sub-sub-sub-directory 221
            - file 2211

Come ottenerlo al meglio in Python?

Risposte:


146

Ecco una funzione per farlo con la formattazione:

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
Ha funzionato molto bene, grazie. Anche se la maggior parte lo saprebbe, sempre a beneficio dei nuovi arrivati ​​in python - tieni presente che dovresti chiamare la funzione alla fine (assumendo Windows), quindi potresti aggiungere una nuova riga alla fine con il contenuto list_files ("D: \\ ")
Rahul

1
Ha funzionato bene su python3. Ma su python2 ValueError: zero length field name in formatviene lanciato.
nipunasudha

3
Se startpath viene ripetuto all'interno di root, non sostituirà ogni occorrenza? Il passaggio a root.replace(startpath, '', 1)dovrebbe risolverlo
drone.ah

31

Simile alle risposte precedenti, ma per python3, probabilmente leggibile e probabilmente estensibile:

from pathlib import Path

class DisplayablePath(object):
    display_filename_prefix_middle = '├──'
    display_filename_prefix_last = '└──'
    display_parent_prefix_middle = '    '
    display_parent_prefix_last = '│   '

    def __init__(self, path, parent_path, is_last):
        self.path = Path(str(path))
        self.parent = parent_path
        self.is_last = is_last
        if self.parent:
            self.depth = self.parent.depth + 1
        else:
            self.depth = 0

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    @classmethod
    def make_tree(cls, root, parent=None, is_last=False, criteria=None):
        root = Path(str(root))
        criteria = criteria or cls._default_criteria

        displayable_root = cls(root, parent, is_last)
        yield displayable_root

        children = sorted(list(path
                               for path in root.iterdir()
                               if criteria(path)),
                          key=lambda s: str(s).lower())
        count = 1
        for path in children:
            is_last = count == len(children)
            if path.is_dir():
                yield from cls.make_tree(path,
                                         parent=displayable_root,
                                         is_last=is_last,
                                         criteria=criteria)
            else:
                yield cls(path, displayable_root, is_last)
            count += 1

    @classmethod
    def _default_criteria(cls, path):
        return True

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    def displayable(self):
        if self.parent is None:
            return self.displayname

        _filename_prefix = (self.display_filename_prefix_last
                            if self.is_last
                            else self.display_filename_prefix_middle)

        parts = ['{!s} {!s}'.format(_filename_prefix,
                                    self.displayname)]

        parent = self.parent
        while parent and parent.parent is not None:
            parts.append(self.display_parent_prefix_middle
                         if parent.is_last
                         else self.display_parent_prefix_last)
            parent = parent.parent

        return ''.join(reversed(parts))

Utilizzo di esempio:

paths = DisplayablePath.make_tree(Path('doc'))
for path in paths:
    print(path.displayable())

Output di esempio:

doc/
├── _static/
   ├── embedded/
      ├── deep_file
      └── very/
          └── deep/
              └── folder/
                  └── very_deep_file
   └── less_deep_file
├── about.rst
├── conf.py
└── index.rst

Appunti

  • Questo usa la ricorsione. Solleverà un RecursionError su alberi di cartelle molto profondi
  • L'albero viene valutato pigramente. Dovrebbe comportarsi bene su alberi di cartelle molto larghi . Tuttavia, i figli immediati di una determinata cartella non vengono valutati pigramente.

Modificare:

  • Bonus aggiunto! callback dei criteri per il filtraggio dei percorsi.

Bello strumento, hai un rapido esempio su come utilizzare i criteri per escludere i nomi delle cartelle?
Matt-Mac-Muffin

Questo e 'esattamente quello che stavo cercando. Grazie mille!
dheinz,

24

Una soluzione senza il tuo rientro:

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

os.walk fa già la camminata top-down, prima in profondità che stai cercando.

Ignorare l'elenco delle directory impedisce la sovrapposizione menzionata.


2
python dice:NameError: name 'path' is not defined
Francesco Mantovani il

1
@FrancescoMantovani "path" è la variabile contenente la directory che vuoi stampare, cioè r "C: \ Users \ username \ Documents \ path"
zwelz

16

Elenca la struttura ad albero delle directory in Python?

Di solito preferiamo usare solo l'albero GNU, ma non lo abbiamo sempre treesu tutti i sistemi e talvolta è disponibile Python 3. Una buona risposta qui potrebbe essere facilmente copiata e incollata e non rendere GNU treeun requisito.

treeL'output di è simile a questo:

$ tree
.
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

Ho creato la struttura di directory sopra nella mia directory home sotto una directory che chiamo pyscratch.

Vedo anche altre risposte qui che si avvicinano a quel tipo di output, ma penso che possiamo fare di meglio, con un codice più semplice e più moderno e approcci di valutazione pigramente.

Albero in Python

Per cominciare, usiamo un esempio che

  • usa l' Pathoggetto Python 3
  • usa le espressioni yielde yield from(che creano una funzione generatore)
  • usa la ricorsione per un'elegante semplicità
  • utilizza commenti e alcune annotazioni di tipo per maggiore chiarezza
from pathlib import Path

# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '


def tree(dir_path: Path, prefix: str=''):
    """A recursive generator, given a directory Path object
    will yield a visual tree structure line by line
    with each line prefixed by the same characters
    """    
    contents = list(dir_path.iterdir())
    # contents each get pointers that are ├── with a final └── :
    pointers = [tee] * (len(contents) - 1) + [last]
    for pointer, path in zip(pointers, contents):
        yield prefix + pointer + path.name
        if path.is_dir(): # extend the prefix and recurse:
            extension = branch if pointer == tee else space 
            # i.e. space because last, └── , above so no more |
            yield from tree(path, prefix=prefix+extension)

e adesso:

for line in tree(Path.home() / 'pyscratch'):
    print(line)

stampe:

├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

Dobbiamo materializzare ogni directory in un elenco perché abbiamo bisogno di sapere quanto è lungo, ma in seguito buttiamo via l'elenco. Per una ricorsione ampia e profonda questo dovrebbe essere abbastanza pigro.

Il codice sopra, con i commenti, dovrebbe essere sufficiente per comprendere appieno cosa stiamo facendo qui, ma sentiti libero di esaminarlo con un debugger per elaborarlo meglio se necessario.

Più funzionalità

Ora GNU treeci offre un paio di funzioni utili che mi piacerebbe avere con questa funzione:

  • stampa prima il nome della directory del soggetto (lo fa automaticamente, il nostro no)
  • stampa il conteggio di n directories, m files
  • opzione per limitare la ricorsione, -L level
  • opzione per limitare solo le directory, -d

Inoltre, quando c'è un albero enorme, è utile limitare l'iterazione (ad esempio con islice) per evitare di bloccare l'interprete con il testo, poiché a un certo punto l'output diventa troppo prolisso per essere utile. Possiamo renderlo arbitrariamente alto per impostazione predefinita, diciamo 1000.

Quindi rimuoviamo i commenti precedenti e compiliamo questa funzionalità:

from pathlib import Path
from itertools import islice

space =  '    '
branch = '│   '
tee =    '├── '
last =   '└── '
def tree(dir_path: Path, level: int=-1, limit_to_directories: bool=False,
         length_limit: int=1000):
    """Given a directory Path object print a visual tree structure"""
    dir_path = Path(dir_path) # accept string coerceable to Path
    files = 0
    directories = 0
    def inner(dir_path: Path, prefix: str='', level=-1):
        nonlocal files, directories
        if not level: 
            return # 0, stop iterating
        if limit_to_directories:
            contents = [d for d in dir_path.iterdir() if d.is_dir()]
        else: 
            contents = list(dir_path.iterdir())
        pointers = [tee] * (len(contents) - 1) + [last]
        for pointer, path in zip(pointers, contents):
            if path.is_dir():
                yield prefix + pointer + path.name
                directories += 1
                extension = branch if pointer == tee else space 
                yield from inner(path, prefix=prefix+extension, level=level-1)
            elif not limit_to_directories:
                yield prefix + pointer + path.name
                files += 1
    print(dir_path.name)
    iterator = inner(dir_path, level=level)
    for line in islice(iterator, length_limit):
        print(line)
    if next(iterator, None):
        print(f'... length_limit, {length_limit}, reached, counted:')
    print(f'\n{directories} directories' + (f', {files} files' if files else ''))

E ora possiamo ottenere lo stesso tipo di output di tree:

tree(Path.home() / 'pyscratch')

stampe:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

E possiamo limitarci a livelli:

tree(Path.home() / 'pyscratch', level=2)

stampe:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
   └── subpackage2
└── package2
    └── __init__.py

4 directories, 3 files

E possiamo limitare l'output alle directory:

tree(Path.home() / 'pyscratch', level=2, limit_to_directories=True)

stampe:

pyscratch
├── package
   ├── subpackage
   └── subpackage2
└── package2

4 directories

Retrospettiva

In retrospettiva, avremmo potuto utilizzare path.globper la corrispondenza. Potremmo anche usarlo path.rglobper il globbing ricorsivo, ma ciò richiederebbe una riscrittura. Potremmo anche usare itertools.teeinvece di materializzare un elenco di contenuti di directory, ma ciò potrebbe avere compromessi negativi e probabilmente renderebbe il codice ancora più complesso.

I commenti sono ben accetti!


Per stampare anche le righe di codice, elif not limit_to_directories:aggiungere quanto segue: info = prefix + pointer + path.name; try: with path.open('r') as f: n_lines = len(f.readlines()); loc = f' LOC: {n_lines}'; info += loc; except UnicodeDecodeError: pass; yield info Vedere questo collegamento per gli spazi vuoti appropriati.
Steven C. Howell

Questo era esattamente ciò di cui avevo bisogno nel mio codice e mi ha insegnato alcuni nuovi trucchi Python! L'unica cosa che vorrei notare è che contentsdeve essere filtrata se limit_to_directoriesè True. In caso contrario, se una cartella non ha una directory per l'ultimo file, l'albero non verrà disegnato correttamente. if limit_to_directories: contents = [path for path in contents if path.is_dir()]
hennign

@ hennign grazie, risposta aggiornata, apprezzo il feedback!
Aaron Hall

Python è tutto basato sulla list(dir_path.iterdir())restituzione di un albero top-down della struttura di directory correttamente ordinato. Vedo tale garanzia nella API per iterdir () . Si prega di fornire un riferimento su come gli iterdir()ordini o è garantito per fornire l'ordine desiderato.
ingyhere

@ingyhere Non sono sicuro di dove ti sia venuta l'idea - sembra che usi os.listdir()di default - che non garantisce l'ordine : "L'elenco è in ordine arbitrario e non include le voci speciali '.' e ".." anche se sono presenti nella directory. "
Aaron Hall

15

Sono venuto qui cercando la stessa cosa e ho usato la risposta dhobbs per me. Come modo per ringraziare la comunità, ho aggiunto alcuni argomenti per scrivere su un file, come ha chiesto akshay, e ho reso la visualizzazione dei file opzionale in modo che non sia così un po 'un output. Inoltre, ha reso il rientro un argomento opzionale in modo da poterlo modificare, poiché ad alcuni piace che sia 2 e altri preferiscono 4.

Utilizzato cicli diversi in modo che quello che non mostra i file non controlli se deve farlo a ogni iterazione.

Spero che aiuti qualcun altro poiché la risposta di dhobbs mi ha aiutato. Molte grazie.

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

Credo che questa risposta non contribuisca alla risposta già accettata. L'unica cosa che fornisci è un codice fluff aggiuntivo per disattivare o meno le funzionalità nella risposta.
CodeLikeBeaker

3
La tua sensazione è giusta, @ jason-heine. La risposta accettata è abbastanza buona, ma alcune persone hanno chiesto come fare queste cose inutili e volevo dare loro qualcosa. Downvote o segnala la mia risposta se non vuoi vederlo in SO, ho pensato che non avrebbe fatto male, ma potrei sbagliarmi.
Rubén Cabrera

3
È davvero utile. Molte grazie. L'ho usato così com'è.
vladblindu

7

Basato su questo fantastico post

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

Ecco un perfezionamento per comportarsi esattamente come

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

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


# tree.py # # Scritto da Doug Dahms # # Stampa la struttura ad albero per il percorso specificato sulla riga di comando





da os import listdir , sep
 da os . percorso import abspath , basename , isdir
 da 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 = ordinato ( files , key = lambda s : s . lower ()) 
    count = 0 
    last = len (  
       files ) - 1 per 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 , Falso )
            
                 
                  
            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 + '\' non è una directory ' else : print usage ()
    
        

if __name__ == '__main__' : 
    main () 


6
import os

def fs_tree_to_dict(path_):
    file_token = ''
    for root, dirs, files in os.walk(path_):
        tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs}
        tree.update({f: file_token for f in files})
        return tree  # note we discontinue iteration trough os.walk

Se qualcuno è interessato, quella funzione ricorsiva restituisce una struttura nidificata di dizionari. Le chiavi sono file systemnomi (di directory e file), i valori sono:

  • dizionari secondari per directory
  • stringhe per file (vedere file_token)

Le stringhe che designano i file sono vuote in questo esempio. Possono anche essere dati il ​​contenuto del file o le informazioni del proprietario o i privilegi o qualsiasi oggetto diverso da un dict. A meno che non si tratti di un dizionario, può essere facilmente distinto da un "tipo di directory" in ulteriori operazioni.

Avere un tale albero in un filesystem:

# bash:
$ tree /tmp/ex
/tmp/ex
├── d_a
   ├── d_a_a
   ├── d_a_b
      └── f1.txt
   ├── d_a_c
   └── fa.txt
├── d_b
   ├── fb1.txt
   └── fb2.txt
└── d_c

Il risultato sarà:

# python 2 or 3:
>>> fs_tree_to_dict("/tmp/ex")
{
    'd_a': {
        'd_a_a': {},
        'd_a_b': {
            'f1.txt': ''
        },
        'd_a_c': {},
        'fa.txt': ''
    },
    'd_b': {
        'fb1.txt': '',
        'fb2.txt': ''
    },
    'd_c': {}
}

Se ti piace, ho già creato un pacchetto (python 2 e 3) con questa roba (e un simpatico pyfakefsaiutante): https://pypi.org/project/fsforge/


4

Oltre alla risposta dhobbs sopra ( https://stackoverflow.com/a/9728478/624597 ), ecco una funzionalità extra per memorizzare i risultati in un file (io personalmente la uso per copiare e incollare su FreeMind per avere una bella panoramica di la struttura, quindi ho usato le tabulazioni al posto degli spazi per il rientro):

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

questa risposta ha davvero aiutato, grazie
prex il

2

È possibile eseguire il comando "albero" della shell di Linux.

Installazione:

   ~$sudo apt install tree

Utilizzo in Python

    >>> import os
    >>> os.system('tree <desired path>')

Esempio:

    >>> os.system('tree ~/Desktop/myproject')

Questo ti dà una struttura più pulita ed è visivamente più completo e facile da digitare.


Questa non è una soluzione molto portatile in quanto non riesce su Windows + si basa su un programma aggiuntivo
oglop

2

Questa soluzione funzionerà solo se hai treeinstallato sul tuo sistema. Tuttavia, lascio questa soluzione qui nel caso in cui aiuti qualcun altro.

Puoi dire ad albero di produrre la struttura ad albero come XML ( tree -X) o JSON ( tree -J). JSON ovviamente può essere analizzato direttamente con python e XML può essere facilmente letto con lxml.

Con la seguente struttura di directory come esempio:

[sri@localhost Projects]$ tree --charset=ascii bands
bands
|-- DreamTroll
|   |-- MattBaldwinson
|   |-- members.txt
|   |-- PaulCarter
|   |-- SimonBlakelock
|   `-- Rob Stringer
|-- KingsX
|   |-- DougPinnick
|   |-- JerryGaskill
|   |-- members.txt
|   `-- TyTabor
|-- Megadeth
|   |-- DaveMustaine
|   |-- DavidEllefson
|   |-- DirkVerbeuren
|   |-- KikoLoureiro
|   `-- members.txt
|-- Nightwish
|   |-- EmppuVuorinen
|   |-- FloorJansen
|   |-- JukkaNevalainen
|   |-- MarcoHietala
|   |-- members.txt
|   |-- TroyDonockley
|   `-- TuomasHolopainen
`-- Rush
    |-- AlexLifeson
    |-- GeddyLee
    `-- NeilPeart

5 directories, 25 files

XML

<?xml version="1.0" encoding="UTF-8"?>
<tree>
  <directory name="bands">
    <directory name="DreamTroll">
      <file name="MattBaldwinson"></file>
      <file name="members.txt"></file>
      <file name="PaulCarter"></file>
      <file name="RobStringer"></file>
      <file name="SimonBlakelock"></file>
    </directory>
    <directory name="KingsX">
      <file name="DougPinnick"></file>
      <file name="JerryGaskill"></file>
      <file name="members.txt"></file>
      <file name="TyTabor"></file>
    </directory>
    <directory name="Megadeth">
      <file name="DaveMustaine"></file>
      <file name="DavidEllefson"></file>
      <file name="DirkVerbeuren"></file>
      <file name="KikoLoureiro"></file>
      <file name="members.txt"></file>
    </directory>
    <directory name="Nightwish">
      <file name="EmppuVuorinen"></file>
      <file name="FloorJansen"></file>
      <file name="JukkaNevalainen"></file>
      <file name="MarcoHietala"></file>
      <file name="members.txt"></file>
      <file name="TroyDonockley"></file>
      <file name="TuomasHolopainen"></file>
    </directory>
    <directory name="Rush">
      <file name="AlexLifeson"></file>
      <file name="GeddyLee"></file>
      <file name="NeilPeart"></file>
    </directory>
  </directory>
  <report>
    <directories>5</directories>
    <files>25</files>
  </report>
</tree>

JSON

[sri@localhost Projects]$ tree -J bands
[
  {"type":"directory","name":"bands","contents":[
    {"type":"directory","name":"DreamTroll","contents":[
      {"type":"file","name":"MattBaldwinson"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"PaulCarter"},
      {"type":"file","name":"RobStringer"},
      {"type":"file","name":"SimonBlakelock"}
    ]},
    {"type":"directory","name":"KingsX","contents":[
      {"type":"file","name":"DougPinnick"},
      {"type":"file","name":"JerryGaskill"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TyTabor"}
    ]},
    {"type":"directory","name":"Megadeth","contents":[
      {"type":"file","name":"DaveMustaine"},
      {"type":"file","name":"DavidEllefson"},
      {"type":"file","name":"DirkVerbeuren"},
      {"type":"file","name":"KikoLoureiro"},
      {"type":"file","name":"members.txt"}
    ]},
    {"type":"directory","name":"Nightwish","contents":[
      {"type":"file","name":"EmppuVuorinen"},
      {"type":"file","name":"FloorJansen"},
      {"type":"file","name":"JukkaNevalainen"},
      {"type":"file","name":"MarcoHietala"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TroyDonockley"},
      {"type":"file","name":"TuomasHolopainen"}
    ]},
    {"type":"directory","name":"Rush","contents":[
      {"type":"file","name":"AlexLifeson"},
      {"type":"file","name":"GeddyLee"},
      {"type":"file","name":"NeilPeart"}
    ]}
  ]},
  {"type":"report","directories":5,"files":25}
]

1

Forse più veloce di @ellockie (forse)

import os
def file_writer (testo):
    con open ("folder_structure.txt", "a") come f_output:
        f_output.write (testo)
def list_files (startpath):


    per root, directory, file in os.walk (startpath):
        livello = root.replace (startpath, '') .count (os.sep)
        rientro = '\ t' * 1 * (livello)
        output_string = '{} {} / \ n'.format (indent, os.path.basename (root))
        file_writer (output_string)
        subindent = '\ t' * 1 * (livello + 1)
        output_string = '% s% s \ n'% (subindent, [f per f nei file])
        file_writer ( ''. join (output_string))


list_files ( "/")

Risultati del test nella schermata seguente:

inserisci qui la descrizione dell'immagine


0

Qui puoi trovare codice con output come questo: https://stackoverflow.com/a/56622847/6671330

V .
|-> V folder1
|   |-> V folder2
|   |   |-> V folder3
|   |   |   |-> file3.txt
|   |   |-> file2.txt
|   |-> V folderX
|   |-> file1.txt
|-> 02-hw1_wdwwfm.py
|-> 06-t1-home1.py
|-> 06-t1-home2.py
|-> hw1.py

0

Per chi sta ancora cercando una risposta. Ecco un approccio ricorsivo per ottenere i percorsi in un dizionario.

import os


def list_files(startpath):
    for root, dirs, files in os.walk(startpath):
        dir_content = []
        for dir in dirs:
            go_inside = os.path.join(startpath, dir)
            dir_content.append(list_files(go_inside))
        files_lst = []
        for f in files:
            files_lst.append(f)
        return {'name': root, 'files': files_lst, 'dirs': dir_content}

0

La risposta di @ dhobbs è fantastica!

ma cambia semplicemente per ottenere facilmente le informazioni sul livello

def print_list_dir(dir):
    print("=" * 64)
    print("[PRINT LIST DIR] %s" % dir)
    print("=" * 64)
    for root, dirs, files in os.walk(dir):
        level = root.replace(dir, '').count(os.sep)
        indent = '| ' * level
        print('{}{} \\'.format(indent, os.path.basename(root)))
        subindent = '| ' * (level + 1)
        for f in files:
            print('{}{}'.format(subindent, f))
    print("=" * 64)

e l'output mi piace

================================================================
[PRINT LIST DIR] ./
================================================================
 \
| os_name.py
| json_loads.py
| linspace_python.py
| list_file.py
| to_gson_format.py
| type_convert_test.py
| in_and_replace_test.py
| online_log.py
| padding_and_clipping.py
| str_tuple.py
| set_test.py
| script_name.py
| word_count.py
| get14.py
| np_test2.py
================================================================

puoi ottenere il livello |contando!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.