2012-03-15 37 views
42

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ê các nội dung cây thư mục đầy đủ:Danh sách cấu trúc cây thư mục trong python?

  • Thư mục con 1:
    • file11
    • file12
    • Sub-sub-directory 11:
      • file111
      • file112
  • Thư mục con 2:
    • file21
    • sub-sub-directory 21
    • sub-sub-directory 22
      • sub-sub-sub-directory 221
        • tập 2211

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

+1

tôi sẽ đề nghị sử dụng 'os.walk () ', nhưng có vẻ như bạn đã ở đó ... bạn đã thử cái gì? –

+0

Tôi đoán đó là bởi vì tôi không hoàn toàn hiểu tuple. Tôi biết làm thế nào để liệt kê tất cả các thư mục và tất cả các tập tin một cách riêng biệt, nhưng tôi không biết làm thế nào để liệt kê các tập tin và thư mục con của một thư mục mà không chồng chéo mọi thứ. – user18115

+1

Xem câu trả lời cho [câu hỏi này] (http://stackoverflow.com/questions/120656/directory-listing-in-python) –

Trả lời

69

Dưới đâ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 sẽ biết, vẫn vì lợi ích của người mới vào python - xin lưu ý rằng bạn sẽ cần phải gọi hàm ở cuối (giả sử các cửa sổ), vì vậy bạn có thể thêm một dòng mới ở cuối với nội dung list_files ("D: \\ ") – Rahul

+0

Làm việc tốt trên python3. Nhưng trên python2 'ValueError: tên trường độ dài bằng không ở định dạng' được ném. – nipunasudha

+0

Hi dhobbs, tôi đã cố gắng sử dụng chức năng của bạn. Tôi tự hỏi nếu có một cách để trả lại cây thư mục này để lặp qua cây thư mục từ thư mục cuối cùng đến một thư mục nào đó! Tôi có thể đăng câu hỏi này nếu bạn muốn. –

16

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

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

os.walk đã hiện từ trên xuống, đi bộ sâu-đầu tiên bạn đang tìm kiếm.

Bỏ qua danh sách thư mục sẽ ngăn không cho chồng chéo bạn đề cập đến.

+0

python nói: 'TênError: tên 'đường dẫn' không được xác định' –

7

Tôi đến đây tìm kiếm điều tương tự và sử dụng dhobbs trả lời 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 một tệp, như akshay đã hỏi và hiển thị các tệp tùy chọn để nó không phải là một kết quả đầu ra. Cũng làm cho thụt đầu dòng thành một tham số tùy chọn để bạn có thể thay đổi nó, vì một số thích nó là 2 và một số khác thích 4.

Sử dụng các vòng lặp khác nhau để không hiển thị các tệp không kiểm tra xem nó có trên mỗi lần lặp hay không.

Hy vọng nó sẽ giúp người 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 
+0

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ã fluff bổ sung để tắt các tính năng hoặc không có trong phản hồi. – CodeLikeBeaker

+1

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 điều này fluff stuff và tôi muốn cung cấp cho một cái gì đó cho họ. Downvote nó hoặc báo cáo câu trả lời của tôi nếu bạn không muốn nhìn thấy điều này trong SO, tôi nghĩ rằng nó sẽ không làm tổn thương, nhưng tôi có thể sai. –

+2

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

4

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

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

Đây es một sàng lọc để hành xử chính xác như

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

Ngày đầu dhobbs trả lời ở trên (https://stackoverflow.com/a/9728478/624597) , đây là một ví dụ chức năng tra lưu trữ kết quả vào một tập tin (cá nhân tôi sử dụng nó để sao chép và dán vào FreeMind để có một cái nhìn tổng quan tốt đẹp của cấu trúc, do đó tôi đã sử dụng các tab thay vì không gian cho indentation):

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

lẽ nhanh hơn @ ellockie (có lẽ)

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

chỉnh sửa: screenshot tôi đã được thử nghiệm là:

enter image description here

Các vấn đề liên quan