180 votes

Lister la structure arborescente d'un répertoire en python ?

Je sais que nous pouvons utiliser os.walk() pour lister tous les sous-répertoires ou tous les fichiers d'un répertoire. Cependant, j'aimerais lister le contenu complet de l'arborescence d'un répertoire :

- 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

Quelle est la meilleure façon d'y parvenir en Python ?

1voto

Enes ERGUN Points 30

Peut-être plus rapide que @ellockie ( Peut-être )

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

Les résultats du test sont présentés dans la capture d'écran ci-dessous :

enter image description here

1voto

Alex Points 11

Python2 et Python3 : J'ai vu plusieurs réponses ici qui sont beaucoup plus conscientes que la mienne, cependant, pour mes applications, je n'avais pas accès aux bibliothèques sur lesquelles ils s'appuyaient. C'est la solution que j'ai trouvée. De plus, pour mon application, j'avais besoin de connaître le chemin absolu de chaque fichier, je l'ai donc imprimé en même temps que le nom du fichier.

#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "

def list_files(startpath):

    for root, dirs, files in os.walk(startpath):
        break

    tree = []    
    for i, file in enumerate(files):
        if i == len(files)-1 and len(dirs) == 0:
            joint = ELBOW
        else:
            joint = TEE
        tree.append('{} {} : {}'.format(joint, file, os.path.join(root, file)))

    for i, dir in enumerate(dirs):
        if i == len(dirs)-1:
            joint = ELBOW
            space = SPACE_PREFIX
        else:
            joint = TEE
            space = PIPE_PREFIX

        tree.append('{} {}/'.format(joint, dir))
        branches = list_files(os.path.join(root,dir))
       for branch in branches:
            tree.append('{}{}'.format(space, branch))

    return tree

if __name__ == '__main__':
    # Obtain top level directory path
    cwd = os.getcwd()
    tree = list_files(cwd)   

    string = '../{}/\n'.format(os.path.basename(cwd))
    for t in tree:
        string += '{}\n'.format(t)
    string = string.replace('\n', '\n   ')
    print(string)

La sortie du script est la suivante :

../TEST_DIR/
├── test.txt : /usr/scripts/TEST_DIR/test.txt
├── a/
│   ├── 1.txt : /usr/scripts/TEST_DIR/a/1.txt
│   ├── 2.py : /usr/scripts/TEST_DIR/a/2.py
│   └── 3.bit : /usr/scripts/TEST_DIR/a/3.bit
├── b/
│   ├── bb/
│   │   ├── 1.txt : /usr/scripts/TEST_DIR/b/bb/1.txt
│   │   ├── 2.py : /usr/scripts/TEST_DIR/b/bb/2.py
│   │   ├── 3.bit : /usr/scripts/TEST_DIR/b/bb/3.bit
│   │   └── bb_copy/
│   │       ├── 1.txt : /usr/scripts/TEST_DIR/b/bb/bb_copy/1.txt
│   │       ├── 2.py : /usr/scripts/TEST_DIR/b/bb/bb_copy/2.py
│   │       ├── 3.bit : /usr/scripts/TEST_DIR/b/bb/bb_copy/3.bit
│   │       └── bb_copy/
│   │           ├── 1.txt : /usr/scripts/TEST_DIR/b/bb/bb_copy/bb_copy/1.txt
│   │           ├── 2.py : /usr/scripts/TEST_DIR/b/bb/bb_copy/bb_copy/2.py
│   │           └── 3.bit : /usr/scripts/TEST_DIR/b/bb/bb_copy/bb_copy/3.bit
│   └── bb_copy/
│       ├── 1.txt : /usr/scripts/TEST_DIR/b/bb_copy/1.txt
│       ├── 2.py : /usr/scripts/TEST_DIR/b/bb_copy/2.py
│       └── 3.bit : /usr/scripts/TEST_DIR/b/bb_copy/3.bit
└── c/

J'apprécierais tout conseil pour rendre ce script plus rationnel, plus conscient et plus robuste. J'espère que cela vous aidera.

0voto

Igor Z Points 51

Vous trouverez ici un code avec un résultat comme celui-ci : 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

0voto

sky Points 50

Pour ceux qui cherchent encore une réponse. Voici une approche récursive pour obtenir les chemins dans un dictionnaire.

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}

0voto

Colin Wang Points 161

Réponse de @dhobbs est formidable !

mais il suffit de changer pour obtenir facilement l'information sur le niveau

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)

et le résultat est le suivant

================================================================
[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
================================================================

vous pouvez obtenir le niveau en | compter !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X