2013-08-23 44 views
48

Tôi đang làm việc trên một tập lệnh đệ quy đi qua các thư mục con trong thư mục chính và tạo danh sách ra khỏi một loại tệp nhất định. Tôi đang gặp sự cố với tập lệnh. Thiết lập hiện tại của nó như sau:Tìm kiếm thư mục con đệ quy và trả về tệp trong danh sách python

for root, subFolder, files in os.walk(PATH): 
    for item in files: 
     if item.endswith(".txt") : 
      fileNamePath = str(os.path.join(root,subFolder,item)) 

vấn đề là biến subFolder đang nằm trong danh sách thư mục con chứ không phải thư mục chứa tệp ITEM. Tôi đã nghĩ đến việc chạy một vòng lặp for cho thư mục con trước và tham gia phần đầu tiên của đường dẫn nhưng tôi đã tìm Id kiểm tra lại để xem có ai có bất kỳ gợi ý nào trước đó không. Cảm ơn bạn đã giúp đỡ!

Trả lời

83

Bạn nên sử dụng dirpath mà bạn gọi là root. Các dirnames được cung cấp để bạn có thể cắt nó nếu có thư mục mà bạn không muốn os.walk để recurse vào.

import os 
result = [os.path.join(dp, f) for dp, dn, filenames in os.walk(PATH) for f in filenames if os.path.splitext(f)[1] == '.txt'] 

Edit:

Sau downvote mới nhất, nó xảy ra với tôi rằng glob là một công cụ tốt hơn để lựa chọn bằng cách mở rộng.

import os 
from glob import glob 
result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], '*.txt'))] 

Cũng là một phiên bản phát

from itertools import chain 
result = (chain.from_iterable(glob(os.path.join(x[0], '*.txt')) for x in os.walk('.'))) 
+0

Điều này sẽ dễ đọc hơn nếu nó không phải là một danh sách hiểu ... –

19

Changed in Python 3.5: Support for recursive globs using “**”.

glob.glob() có một mới recursive parameter.

Nếu bạn muốn nhận được mỗi .txt tập tin dưới my_path (đệ quy trong đó có subdirs):

import glob 

files = glob.glob(my_path + '/**/*.txt', recursive=True) 

# my_path/  the dir 
# **/  every file and dir under my_path 
# *.txt  every file that ends with '.txt' 

Nếu bạn cần một iterator bạn có thể sử dụng iglob như một sự thay thế:

for file in glob.iglob(my_path, recursive=False): 
    # ... 
+1

LoạiError: glob() có một đối số từ khóa không mong muốn 'đệ quy' – CyberJacob

+0

Nó sẽ hoạt động. Đảm bảo bạn sử dụng phiên bản> = 3.5. Tôi đã thêm một liên kết đến tài liệu trong câu trả lời của tôi để biết thêm chi tiết. – Rotareti

+0

Đó là lý do tại sao, tôi đang ở trên 2,7 – CyberJacob

2

của nó không phải là hầu hết các câu trả lời pythonic, nhưng tôi sẽ đặt nó ở đây cho vui vì nó là một bài học gọn gàng trong đệ quy

def find_files(files, dirs=[], extensions=[]): 
    new_dirs = [] 
    for d in dirs: 
     try: 
      new_dirs += [ os.path.join(d, f) for f in os.listdir(d) ] 
     except OSError: 
      if os.path.splitext(d)[1] in extensions: 
       files.append(d) 

    if new_dirs: 
     find_files(files, new_dirs, extensions) 
    else: 
     return 

Trên máy tính của tôi, tôi có hai thư mục, rootroot2

[email protected] ]ls -R root root2 
root: 
temp1 temp2 

root/temp1: 
temp1.1 temp1.2 

root/temp1/temp1.1: 
f1.mid 

root/temp1/temp1.2: 
f.mi f.mid 

root/temp2: 
tmp.mid 

root2: 
dummie.txt temp3 

root2/temp3: 
song.mid 

phép nói rằng tôi muốn tìm tất cả .txt và tất cả .mid tập tin trong một trong các thư mục, sau đó tôi chỉ có thể làm

files = [] 
find_files(files, dirs=['root','root2'], extensions=['.mid','.txt']) 
print(files) 

#['root2/dummie.txt', 
# 'root/temp2/tmp.mid', 
# 'root2/temp3/song.mid', 
# 'root/temp1/temp1.1/f1.mid', 
# 'root/temp1/temp1.2/f.mid']