Daftar struktur pohon direktori di python?

111

Saya tahu bahwa kita dapat menggunakan os.walk()daftar semua sub-direktori atau semua file dalam sebuah direktori. Namun, saya ingin membuat daftar isi pohon direktori lengkap:

- 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

Bagaimana cara terbaik mencapai ini dengan Python?

cinny
sumber

Jawaban:

146

Berikut fungsi untuk melakukannya dengan pemformatan:

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))
dhobbs.dll
sumber
1
Ini bekerja dengan sangat baik, terima kasih. Meskipun sebagian besar akan tahu, masih untuk kepentingan pendatang baru di python - harap dicatat bahwa Anda perlu memanggil fungsi di akhir (dengan asumsi jendela), jadi Anda dapat menambahkan baris baru di akhir dengan konten list_files ("D: \\ ")
Rahul
1
Bekerja dengan baik di python3. Tapi di python2 ValueError: zero length field name in formatterlempar.
nipunasudha
3
Jika startpath diulang di dalam root, bukankah itu menggantikan setiap kejadian? Mengubah ke root.replace(startpath, '', 1)harus memperbaikinya
drone.ah
31

Mirip dengan jawaban di atas, tetapi untuk python3, bisa dibilang bisa dibaca dan bisa dibilang bisa diperluas:

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))

Contoh penggunaan:

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

Contoh keluaran:

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

Catatan

  • Ini menggunakan rekursi. Ini akan memunculkan RecursionError pada pohon folder yang sangat dalam
  • Pohon itu dievaluasi dengan malas. Ini harus berperilaku baik pada pohon folder yang sangat lebar . Turunan langsung dari folder tertentu tidak dievaluasi dengan malas.

Edit:

  • Bonus tambahan! kriteria callback untuk memfilter jalur.
abstrus
sumber
Alat yang bagus, apakah Anda memiliki contoh singkat tentang cara menggunakan kriteria untuk mengecualikan nama folder?
Matt-Mac-Muffin
Inilah yang saya cari. Terima kasih banyak!
dheinz
24

Solusi tanpa lekukan Anda:

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

os.walk sudah melakukan penjelajahan top-down, kedalaman-pertama yang Anda cari.

Mengabaikan daftar dirs mencegah tumpang tindih yang Anda sebutkan.

Intra
sumber
2
python mengatakan:NameError: name 'path' is not defined
Francesco Mantovani
1
@FrancescoMantovani "path" adalah variabel yang berisi direktori yang ingin Anda cetak, yaitu r "C: \ Users \ username \ Documents \ path"
zwelz
16

Daftar struktur pohon direktori dengan Python?

Kami biasanya lebih suka menggunakan pohon GNU, tetapi kami tidak selalu memiliki treepada setiap sistem, dan terkadang Python 3 tersedia. Jawaban yang baik di sini dapat dengan mudah disalin-tempel dan tidak menjadikan GNU treesebagai persyaratan.

treeOutputnya terlihat seperti ini:

$ 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

Saya membuat struktur direktori di atas di direktori home saya di bawah direktori yang saya sebut pyscratch.

Saya juga melihat jawaban lain di sini yang mendekati keluaran semacam itu, tetapi saya pikir kita bisa melakukan lebih baik, dengan kode yang lebih sederhana, lebih modern dan pendekatan evaluasi malas.

Pohon dengan Python

Untuk memulai, mari gunakan contoh itu

  • menggunakan Python 3 Path objek
  • menggunakan yielddanyield from ekspresi (yang membuat fungsi generator)
  • menggunakan rekursi untuk kesederhanaan yang elegan
  • menggunakan komentar dan beberapa jenis anotasi untuk kejelasan ekstra
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)

dan sekarang:

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

cetakan:

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

Kita memang perlu mewujudkan setiap direktori menjadi sebuah daftar karena kita perlu mengetahui berapa panjangnya, tetapi setelah itu kita membuang daftarnya. Untuk rekursi yang dalam dan luas, ini harus cukup malas.

Kode di atas, dengan komentar, seharusnya cukup untuk memahami sepenuhnya apa yang kita lakukan di sini, tetapi jangan ragu untuk melangkah melewatinya dengan debugger untuk lebih baik jika Anda perlu.

Lebih banyak fitur

Sekarang GNU treememberi kita beberapa fitur berguna yang saya ingin miliki dengan fungsi ini:

  • mencetak nama direktori subjek terlebih dahulu (melakukannya secara otomatis, milik kami tidak)
  • mencetak hitungan n directories, m files
  • opsi untuk membatasi rekursi, -L level
  • pilihan untuk membatasi hanya pada direktori, -d

Juga, ketika ada pohon besar, akan berguna untuk membatasi iterasi (misalnya dengan islice) untuk menghindari penguncian interpreter Anda dengan teks, karena pada titik tertentu hasilnya menjadi terlalu bertele-tele untuk digunakan. Kita dapat membuat ini menjadi tinggi secara default - katakanlah1000 .

Jadi mari kita hapus komentar sebelumnya dan isi fungsi ini:

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 ''))

Dan sekarang kita bisa mendapatkan jenis keluaran yang sama seperti tree:

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

cetakan:

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

Dan kami dapat membatasi ke level:

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

cetakan:

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

4 directories, 3 files

Dan kita dapat membatasi output ke direktori:

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

cetakan:

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

4 directories

Retrospektif

Dalam retrospeksi, kita bisa digunakan path.globuntuk pencocokan. Kita mungkin juga bisa menggunakan path.rglobuntuk rekursif globbing, tapi itu akan membutuhkan penulisan ulang. Kita juga dapat menggunakan itertools.teealih-alih membuat daftar isi direktori, tetapi itu bisa memiliki pengorbanan negatif dan mungkin akan membuat kode menjadi lebih kompleks.

Komentar dipersilakan!

Aaron Hall
sumber
Untuk juga mencetak baris kode, setelah elif not limit_to_directories:menambahkan yang berikut ini: 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 Lihat tautan ini untuk ruang kosong yang tepat.
Steven C. Howell
Inilah yang saya butuhkan dalam kode saya, dan mengajari saya beberapa trik Python baru! Satu-satunya hal yang saya perhatikan adalah yang contentsperlu disaring jika limit_to_directoriesBenar. Jika tidak, jika folder tidak memiliki direktori untuk file terakhir, pohon tidak akan digambar dengan benar. if limit_to_directories: contents = [path for path in contents if path.is_dir()]
hennign
@hennign terima kasih, jawaban diperbarui, hargai umpan baliknya!
Aaron Hall
Python semuanya didasarkan pada list(dir_path.iterdir())pengembalian pohon struktur direktori top-down yang disusun dengan benar. Saya tidak melihat jaminan seperti itu di API untuk iterdir () . Mohon berikan referensi tentang bagaimana iterdir()pemesanan atau jaminan memberikan pemesanan yang diinginkan.
ingyhere
@ingyhere Saya tidak yakin dari mana Anda mendapatkan ide itu - sepertinya digunakan os.listdir()secara default - yang tidak menjamin urutan : "Daftar ini dalam urutan sewenang-wenang, dan tidak menyertakan entri khusus '.' dan '..' meskipun mereka ada di direktori. "
Aaron Hall
15

Saya datang ke sini mencari hal yang sama dan menggunakan jawaban dhobbs untuk saya. Sebagai cara untuk berterima kasih kepada komunitas, saya menambahkan beberapa argumen untuk ditulis ke file, seperti yang diminta akshay, dan membuat menampilkan file opsional sehingga tidak terlalu menjadi output. Juga jadikan indentasi sebagai argumen opsional sehingga Anda dapat mengubahnya, karena beberapa menyukainya menjadi 2 dan yang lain memilih 4.

Menggunakan loop yang berbeda sehingga yang tidak menampilkan file tidak memeriksa apakah itu harus pada setiap iterasi.

Semoga ini membantu orang lain karena jawaban dhobbs membantu saya. Terima kasih banyak.

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
Rubén Cabrera
sumber
Saya merasa jawaban ini tidak berkontribusi pada jawaban yang sudah diterima. Satu-satunya hal yang Anda sediakan adalah kode fluff tambahan untuk mematikan fitur atau tidak dalam respons.
CodeLikeBeaker
3
Perasaan Anda benar, @ jason-heine. Jawaban yang diterima cukup baik, tetapi beberapa orang bertanya bagaimana melakukan hal-hal yang tidak menyenangkan ini dan saya ingin memberikan sesuatu kepada mereka. Turunkan atau laporkan jawaban saya jika Anda tidak ingin melihat ini di SO, saya pikir tidak ada salahnya, tetapi saya mungkin salah.
Rubén Cabrera
3
Ini memang berguna. Terima kasih banyak. Saya menggunakannya apa adanya.
vladblindu
7

Berdasarkan postingan fantastis ini

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

Inilah perbaikan untuk berperilaku persis seperti

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

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

# tree.py # # Ditulis oleh Doug Dahms #



 # Mencetak struktur pohon untuk jalur yang ditentukan pada baris perintah

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

def tree ( dir , padding , print_files = False , isLast = False , isFirst = False '└──' + basename ( abspath ( dir )) else : print padding . decode ( dir ) if isdir ( dir + sep + x )] ): if isFirst : print padding . decode ( 'utf8' ) [: - 1 ]. encode ( 'utf8' ) + dir
     else : if isLast : print padding . decode ( 'utf8' ) [: - 1 penyandian
    
         
        
             ]. ( 'utf8' ) + 'utf8' ) [: - 1 ]. menyandikan ( 'utf8' ) + '├──' + nama dasar ( abspath ( dir )) 
    files = [] if print_files : 
        files = listdir ( dir ) lain :   
        
                
    
     
        file= [ X untuk x di listdir ( jika tidak isFirst : 
        Padding = bantalan + '' 
    file = diurutkan ( file , kunci = lambda s : s . RENDAH ()) 
    hitung = 0 
    terakhir = len  
        (file ) - 1 untuk i , file di enumerate ( file ): 
        hitung + = 1 
        jalur = dir + sep + file  
     
        isLast = i == terakhir
         if isdir ( path ): if count == len ( files ): if isFirst : 
                    tree ( path , padding , print_files , isLast , False ) else : 
                    tree ( path , padding + '' , print_files , isLast , Salah )
            
                 
                  
             lain : 
                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 ] jika isdir ( path ):
        
            tree(path, '', True, False, True)
        else:
            print 'ERROR: \'' + path + '\' bukan direktori ' else : penggunaan cetak ()
    
        

jika __name__ == '__main__' : 
    main () 

albfan.dll
sumber
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

Jika ada yang tertarik - fungsi rekursif itu mengembalikan struktur kamus bersarang. Kunci adalah file systemnama (direktori dan file), nilainya adalah:

  • sub kamus untuk direktori
  • string untuk file (lihat file_token)

String yang menunjuk file kosong dalam contoh ini. Mereka juga dapat diberi konten file atau info pemilik atau hak istimewa atau objek apa pun selain dict. Kecuali itu kamus, ini dapat dengan mudah dibedakan dari "jenis direktori" dalam operasi lebih lanjut.

Memiliki pohon seperti itu dalam sistem file:

# 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

Hasilnya adalah:

# 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': {}
}

Jika Anda seperti itu, saya sudah membuat paket (python 2 & 3) dengan barang-barang ini (dan pyfakefspembantu yang bagus ): https://pypi.org/project/fsforge/

Mikaelblomkvistsson
sumber
4

Di atas jawaban dhobbs di atas ( https://stackoverflow.com/a/9728478/624597 ), berikut adalah fungsi tambahan untuk menyimpan hasil ke file (saya pribadi menggunakannya untuk menyalin dan menempel ke FreeMind untuk mendapatkan gambaran umum yang bagus tentang strukturnya, oleh karena itu saya menggunakan tab, bukan spasi untuk lekukan):

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(".")
Ellockie
sumber
jawaban ini sangat membantu, terima kasih
prex
2

Anda dapat menjalankan perintah 'pohon' dari shell Linux.

Instalasi:

   ~$sudo apt install tree

Menggunakan dalam python

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

Contoh:

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

Ini memberi Anda struktur yang lebih bersih dan secara visual lebih komprehensif dan mudah untuk mengetik.

Ashfaq Ur Rahman N
sumber
Ini bukan solusi yang sangat portabel karena ini gagal pada Windows + bergantung pada program tambahan
oglop
2

Solusi ini hanya akan berfungsi jika Anda telah treemenginstal di sistem Anda. Namun saya meninggalkan solusi ini di sini kalau-kalau itu membantu orang lain.

Anda bisa memberi tahu pohon untuk mengeluarkan struktur pohon sebagai XML ( tree -X) atau JSON ( tree -J). JSON tentu saja dapat diurai langsung dengan python dan XML dengan mudah dapat dibaca lxml.

Dengan struktur direktori berikut sebagai contoh:

[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}
]
lihai
sumber
1

Mungkin lebih cepat dari @ellockie (Mungkin)

impor os
def file_writer (teks):
    dengan open ("folder_structure.txt", "a") sebagai f_output:
        f_output.write (teks)
def list_files (jalur start):


    untuk root, dirs, file di os.walk (startpath):
        level = root.replace (startpath, '') .count (os.sep)
        indentasi = '\ t' * 1 * (level)
        output_string = '{} {} / \ n'.format (indentasi, os.path.basename (root))
        file_writer (string_luaran)
        subindent = '\ t' * 1 * (level + 1)
        output_string = '% s% s \ n'% (subindentasi, [f untuk f dalam file])
        file_writer (". join (output_string))


list_files ("/")

Hasil tes pada screenshot di bawah ini:

masukkan deskripsi gambar di sini

Enes ERGUN
sumber
0

Di sini Anda dapat menemukan kode dengan keluaran seperti ini: 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
Igor Z
sumber
0

Bagi mereka yang masih mencari jawaban. Berikut adalah pendekatan rekursif untuk mendapatkan jalur dalam kamus.

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}
langit
sumber
0

Jawaban @ dhobbs luar biasa!

tetapi cukup ubah agar mudah mendapatkan info level

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)

dan hasilnya seperti

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

Anda bisa mendapatkan level dengan |hitungan!

Colin Wang
sumber