Liệt kê cấu trúc cây thư mục trong python?


111

Tôi biết rằng chúng ta có thể sử dụng os.walk()để liệt kê tất cả các thư mục con hoặc tất cả các tệp trong một thư mục. Tuy nhiên, tôi muốn liệt kê toàn bộ nội dung cây thư mục:

- 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

Làm thế nào để đạt được điều này tốt nhất trong Python?

Câu trả lời:


146

Đây là một chức năng để làm điều đó với định dạng:

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
Điều này làm việc rất tốt, cảm ơn bạn. Mặc dù hầu hết đều biết, nhưng vẫn vì lợi ích của những người mới tham gia python - xin lưu ý rằng bạn sẽ cần gọi hàm ở cuối (giả sử là windows), vì vậy bạn có thể thêm một dòng mới ở cuối với content list_files ("D: \\ ")
Rahul

1
Hoạt động tốt trên python3. Nhưng trên python2 ValueError: zero length field name in formatbị ném.
nipunasudha

3
Nếu startpath được lặp lại trong root, nó sẽ không thay thế mỗi lần xuất hiện? Thay đổi để root.replace(startpath, '', 1)khắc phục điều đó
drone.ah

31

Tương tự như các câu trả lời ở trên, nhưng đối với python3, có thể đọc được và có thể mở rộng:

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

Ví dụ sử dụng:

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

Ví dụ đầu ra:

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

Ghi chú

  • Điều này sử dụng đệ quy. Nó sẽ gây ra lỗi Đệ quy trên các cây thư mục thực sự sâu
  • Cây được đánh giá một cách lười biếng. Nó sẽ hoạt động tốt trên các cây thư mục thực sự rộng . Tuy nhiên, phần con ngay lập tức của một thư mục nhất định không được đánh giá một cách lười biếng.

Biên tập:

  • Đã thêm tiền thưởng! gọi lại tiêu chí cho các đường dẫn lọc.

Thật tuyệt, bạn có ví dụ nhanh về cách sử dụng tiêu chí để loại trừ tên thư mục không?
Matt-Mac-Muffin

Điều này thật đúng với gì mà tôi đã tìm kiếm. Cảm ơn bạn rất nhiều!
dheinz

24

Một giải pháp mà không cần thụt lề của bạn:

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

os.walk đã thực hiện bước đi từ trên xuống, theo chiều sâu mà bạn đang tìm kiếm.

Bỏ qua danh sách dirs ngăn chặn sự chồng chéo mà bạn đề cập.


2
python nói:NameError: name 'path' is not defined
Francesco Mantovani

1
@FacescoMantovani "path" là biến chứa thư mục bạn muốn in, tức là r "C: \ Users \ tên người dùng \ Documents \ path"
Philly

16

Liệt kê cấu trúc cây thư mục trong Python?

Chúng tôi thường thích chỉ sử dụng GNU tree, nhưng không phải lúc nào chúng tôi cũng có treetrên mọi hệ thống và đôi khi Python 3 cũng có sẵn. Một câu trả lời hay ở đây có thể dễ dàng được sao chép và không làm cho GNU trở thành treemột yêu cầu.

treeđầu ra của trông như thế này:

$ 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

Tôi đã tạo cấu trúc thư mục trên trong thư mục chính của mình trong một thư mục mà tôi gọi pyscratch.

Tôi cũng thấy các câu trả lời khác ở đây tiếp cận loại đầu ra đó, nhưng tôi nghĩ chúng ta có thể làm tốt hơn, với mã đơn giản hơn, hiện đại hơn và cách tiếp cận đánh giá lười biếng.

Cây trong Python

Để bắt đầu, hãy sử dụng một ví dụ

  • sử dụng Pathđối tượng Python 3
  • sử dụng các biểu thức yieldyield from(tạo một hàm trình tạo)
  • sử dụng đệ quy cho sự đơn giản thanh lịch
  • sử dụng nhận xét và một số loại chú thích để thêm rõ ràng
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)

và bây giờ:

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

bản in:

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

Chúng ta cần cụ thể hóa từng thư mục thành một danh sách vì chúng ta cần biết nó dài bao lâu, nhưng sau đó chúng ta sẽ vứt bỏ danh sách. Đối với đệ quy sâu và rộng, điều này sẽ đủ lười biếng.

Đoạn mã ở trên, với các nhận xét, sẽ đủ để hiểu đầy đủ những gì chúng tôi đang làm ở đây, nhưng vui lòng xem qua nó với trình gỡ lỗi để kiểm tra nó tốt hơn nếu bạn cần.

Các tính năng khác

Bây giờ GNU treecung cấp cho chúng ta một số tính năng hữu ích mà tôi muốn có với chức năng này:

  • in tên thư mục chủ đề trước (tự động làm như vậy, của chúng tôi thì không)
  • in số lượng n directories, m files
  • tùy chọn để giới hạn đệ quy, -L level
  • tùy chọn để giới hạn chỉ trong các thư mục, -d

Ngoài ra, khi có một cây lớn, bạn nên hạn chế lặp lại (ví dụ: với islice) để tránh khóa trình thông dịch của bạn với văn bản, vì tại một số điểm, kết quả đầu ra trở nên quá dài dòng không hữu ích. Theo mặc định, chúng tôi có thể đặt mức này cao tùy ý - giả sử 1000.

Vì vậy, hãy xóa các nhận xét trước đó và điền vào chức năng này:

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

Và bây giờ chúng ta có thể nhận được cùng một loại đầu ra như tree:

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

bản in:

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

Và chúng tôi có thể hạn chế ở các cấp độ:

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

bản in:

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

4 directories, 3 files

Và chúng tôi có thể giới hạn đầu ra cho các thư mục:

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

bản in:

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

4 directories

Hồi tưởng

Nhìn lại, chúng tôi có thể đã sử dụng path.globđể đối sánh. Có lẽ chúng ta cũng có thể sử dụng path.rglobcho việc đánh bóng đệ quy, nhưng điều đó sẽ yêu cầu viết lại. Chúng tôi cũng có thể sử dụng itertools.teethay vì hiện thực hóa danh sách nội dung thư mục, nhưng điều đó có thể có những đánh đổi tiêu cực và có thể sẽ làm cho mã trở nên phức tạp hơn.

Bình luận được chào đón!


Để in các dòng mã, sau khi elif not limit_to_directories:thêm các dòng sau: 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 Xem liên kết này để biết khoảng trắng thích hợp.
Steven C. Howell

Đây chính xác là những gì tôi cần trong mã của mình và đã dạy tôi một số thủ thuật Python mới! Chỉ có điều tôi muốn lưu ý là nó contentscần được lọc nếu limit_to_directorieslà True. Ngược lại, nếu một thư mục không có thư mục cho tệp cuối cùng, cây sẽ không được vẽ chính xác. if limit_to_directories: contents = [path for path in contents if path.is_dir()]
hen lành

@hen Lành cảm ơn, câu trả lời được cập nhật, đánh giá cao phản hồi!
Aaron Hall

Tất cả Python đều được dự đoán trên việc list(dir_path.iterdir())trả về một cây cấu trúc thư mục được sắp xếp đúng thứ tự từ trên xuống. Tôi không thấy đảm bảo nào như vậy trong API cho iterdir () . Vui lòng cung cấp tài liệu tham khảo về cách thức iterdir()đặt hàng hoặc được đảm bảo cung cấp đơn đặt hàng mong muốn.
ingyhere

@ingyhere Tôi không chắc bạn lấy ý tưởng đó ở đâu - có vẻ nhưos.listdir() nó được sử dụng theo mặc định - điều này không đảm bảo thứ tự : "Danh sách theo thứ tự tùy ý và không bao gồm các mục nhập đặc biệt '.' và '..' ngay cả khi chúng có trong thư mục. "
Aaron Hall

15

Tôi đến đây để tìm kiếm điều tương tự và sử dụng câu trả lời dhobbs cho tôi. Như một cách để cảm ơn cộng đồng, tôi đã thêm một số đối số để ghi vào tệp, như akshay đã yêu cầu và làm cho việc hiển thị tệp là tùy chọn để nó không phải là đầu ra quá bit. Cũng đặt thụt lề trở thành đối số tùy chọn để bạn có thể thay đổi nó, vì một số thích nó là 2 và những người khác thích 4.

Đã sử dụng các vòng lặp khác nhau để một trong những không hiển thị tệp không kiểm tra xem nó có phải trên mỗi lần lặp hay không.

Hy vọng nó sẽ giúp ai đó khác như câu trả lời dhobbs đã giúp tôi. Cảm ơn rất nhiều.

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

Tôi cảm thấy câu trả lời này không góp phần vào câu trả lời đã được chấp nhận. Điều duy nhất bạn đang cung cấp là mã lông tơ bổ sung để tắt các tính năng hoặc không trong phản hồi.
CodeLikeBeaker

3
Cảm giác của bạn là đúng, @ jason-heine. Câu trả lời được chấp nhận là đủ tốt, nhưng một số người hỏi làm thế nào để làm những thứ lông tơ này và tôi muốn tặng một cái gì đó cho họ. Từ chối nó hoặc báo cáo câu trả lời của tôi nếu bạn không muốn thấy điều này trong SO, tôi nghĩ nó sẽ không đau, nhưng tôi có thể sai.
Rubén Cabrera

3
Nó thực sự hữu ích. Cảm ơn rất nhiều. Tôi đã sử dụng nó như nó là.
vladblindu

7

Dựa trên bài đăng tuyệt vời này

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

Đây là một sự sàng lọc để hoạt động chính xác như

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

#! / usr / bin / env python2 # - * - mã hóa: utf-8 - * -


# tree.py # # Viết bởi Doug Dahms # # In cấu trúc cây cho đường dẫn được chỉ định trên dòng lệnh





from os import listdir , sep
 từ os . con đường nhập khẩu abspath , basename , isdir
 từ sys nhập khẩu argv

cây def ( dir , padding , print_files = False , isLast = False , isFirst = False ): if isFirst : in 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 :   
        
                
    
    
        file = [ x cho x trong listdir ( dir ) nếu isdir ( dir + Tháng Chín + x )] nếu không isFirst : 
        đệm = đệm + '' 
    file = sắp xếp ( file , key = lambda s : s . giảm ()) 
    đếm = 0 
    last = len (  
       tệp ) - 1 cho tôi , tệp trong liệt kê ( tệp ): 
        đếm + = 1 
        đường dẫn = dir + sep + tệp  
     
        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 , Sai )
            
                 
                  
            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 + '\' không phải là một thư mục ' else : print use ()
    
        

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

Nếu ai đó quan tâm - hàm đệ quy đó trả về cấu trúc lồng nhau của từ điển. Khóa là file systemtên (của thư mục và tệp), giá trị là:

  • từ điển phụ cho thư mục
  • chuỗi cho các tệp (xem file_token)

Các tệp chỉ định chuỗi trống trong ví dụ này. Chúng cũng có thể là nội dung tệp đã cho hoặc thông tin chủ sở hữu hoặc đặc quyền của nó hoặc bất kỳ đối tượng nào khác với chính tả. Trừ khi đó là một từ điển, nó có thể dễ dàng phân biệt với "loại thư mục" trong các thao tác tiếp theo.

Có một cây như vậy trong hệ thống tệp:

# 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

Kết quả sẽ là:

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

Nếu bạn thích điều đó, tôi đã tạo một gói (python 2 & 3) với nội dung này (và một trình pyfakefstrợ giúp tốt đẹp ): https://pypi.org/project/fsforge/


4

Ngoài câu trả lời dhobbs ở trên ( https://stackoverflow.com/a/9728478/624597 ), đây là một chức năng bổ sung để lưu trữ kết quả vào một tệp (Cá nhân tôi sử dụng nó để sao chép và dán vào FreeMind để có cái nhìn tổng quan về cấu trúc, do đó tôi đã sử dụng các tab thay vì dấu cách để thụt lề):

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

câu trả lời này thực sự hữu ích, cảm ơn
prex

2

Bạn có thể thực hiện lệnh 'cây' của Linux shell.

Cài đặt:

   ~$sudo apt install tree

Sử dụng trong python

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

Thí dụ:

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

Điều này mang lại cho bạn một cấu trúc rõ ràng hơn và trực quan hơn và dễ nhập hơn.


Đây không phải là giải pháp rất xách tay như thế này không thành công trên Windows + dựa trên chương trình bổ sung
con Oglop

2

Giải pháp này sẽ chỉ hoạt động nếu bạn đã treecài đặt trên hệ thống của mình. Tuy nhiên, tôi để giải pháp này ở đây chỉ trong trường hợp nó giúp ích cho người khác.

Bạn có thể yêu cầu cây xuất ra cấu trúc cây dưới dạng XML ( tree -X) hoặc JSON ( tree -J). JSON tất nhiên có thể được phân tích cú pháp trực tiếp bằng python và XML có thể dễ dàng được đọc bằng lxml.

Với cấu trúc thư mục sau làm ví dụ:

[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

Có thể nhanh hơn @ellockie (Có thể)

nhập hệ điều hành
def file_writer (văn bản):
    với open ("folder_ architecture.txt", "a") là f_output:
        f_output.write (văn bản)
def list_files (startpath):


    cho root, dirs, tệp trong os.walk (startpath):
        level = root.replace (startpath, '') .count (os.sep)
        thụt lề = '\ t' * 1 * (cấp độ)
        output_string = '{} {} / \ n'.format (thụt lề, os.path.basename (root))
        file_writer (output_string)
        subindent = '\ t' * 1 * (cấp + 1)
        output_string = '% s% s \ n'% (subindent, [f for f in files])
        file_writer (''. tham gia (output_string))


list_files ("/")

Kết quả kiểm tra trong ảnh chụp màn hình bên dưới:

nhập mô tả hình ảnh ở đây


0

Tại đây bạn có thể tìm thấy mã có đầu ra như thế này: 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

Dành cho những ai vẫn đang tìm kiếm câu trả lời. Đây là một cách tiếp cận đệ quy để lấy các đường dẫn trong từ điển.

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

Câu trả lời của @ dhobbs thật tuyệt!

nhưng chỉ cần thay đổi để dễ dàng nhận được thông tin cấp độ

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)

và đầu ra như thế nào

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

bạn có thể nhận được cấp độ bằng cách |đếm!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.