Thư mục danh sách Python, thư mục con và tệp


130

Tôi đang cố gắng tạo một tập lệnh để liệt kê tất cả thư mục, thư mục con và tệp trong một thư mục đã cho.
Tôi đã thử điều này:

import sys,os

root = "/home/patate/directory/"
path = os.path.join(root, "targetdirectory")

for r,d,f in os.walk(path):
    for file in f:
        print os.path.join(root,file)

Thật không may, nó không hoạt động đúng.
Tôi nhận được tất cả các tập tin, nhưng không phải là đường dẫn đầy đủ của họ.

Ví dụ: nếu cấu trúc dir sẽ là:

/home/patate/directory/targetdirectory/123/456/789/file.txt

Nó sẽ in:

/home/patate/directory/targetdirectory/file.txt

Điều tôi cần là kết quả đầu tiên. Mọi sự trợ giúp sẽ rất được trân trọng! Cảm ơn.

Câu trả lời:


225

Sử dụng os.path.joinđể nối các thư mục và tập tin tên :

for path, subdirs, files in os.walk(root):
    for name in files:
        print os.path.join(path, name)

Lưu ý việc sử dụng pathvà không roottrong phần ghép, vì việc sử dụng rootsẽ không chính xác.


Trong Python 3.4, mô-đun pathlib đã được thêm vào để thao tác đường dẫn dễ dàng hơn. Vì vậy, tương đương với os.path.joinsẽ là:

pathlib.PurePath(path, name)

Ưu điểm pathliblà bạn có thể sử dụng nhiều phương thức hữu ích trên các đường dẫn. Nếu bạn sử dụng Pathbiến thể cụ thể, bạn cũng có thể thực hiện các cuộc gọi hệ điều hành thực tế thông qua chúng, như chand vào một thư mục, xóa đường dẫn, mở tệp mà nó trỏ tới và nhiều hơn nữa.


đây là câu trả lời hữu ích và duy nhất cho nhiều câu hỏi đã được hỏi liên quan đến "làm thế nào để có được tất cả các tệp đệ quy trong python".
harrisonfooord

danh sách hiểu: all_files = [os.path.join (đường dẫn, tên) cho tên trong các tệp cho đường dẫn, thư mục con, tệp trong os.walk (thư mục)]
Nir

45

Chỉ trong trường hợp ... Lấy tất cả các tệp trong thư mục và thư mục con khớp với một số mẫu (ví dụ * .py):

import os
from fnmatch import fnmatch

root = '/some/directory'
pattern = "*.py"

for path, subdirs, files in os.walk(root):
    for name in files:
        if fnmatch(name, pattern):
            print os.path.join(path, name)

10

Đây là một lót:

import os

[val for sublist in [[os.path.join(i[0], j) for j in i[2]] for i in os.walk('./')] for val in sublist]
# Meta comment to ease selecting text

Hầu hết các val for sublist in ...vòng lặp bên ngoài làm phẳng danh sách là một chiều. Các jvòng lặp thu thập một danh sách của tất cả các tập tin và basename gia nhập nó vào đường dẫn hiện tại. cuối cùngi vòng lặp lặp trên tất cả các thư mục và thư mục con.

Ví dụ này sử dụng đường dẫn được mã hóa cứng ./trongos.walk(...) cuộc gọi, bạn có thể bổ sung bất kỳ chuỗi đường dẫn nào bạn muốn.

Lưu ý: os.path.expanduservà / hoặc os.path.expandvarscó thể được sử dụng cho các chuỗi đường dẫn như~/

Mở rộng ví dụ này:

Thật dễ dàng để thêm vào các bài kiểm tra tên cơ sở tập tin và kiểm tra giám đốc.

Ví dụ: kiểm tra *.jpgtệp:

... for j in i[2] if j.endswith('.jpg')] ...

Ngoài ra, không bao gồm .gitthư mục:

... for i in os.walk('./') if '.git' not in i[0].split('/')]

Nó không hoạt động, nhưng để kêu lên .git directoy, bạn cần kiểm tra xem '.git' KHÔNG vào đường dẫn.
La Mã

Vâng. Nên là nếu '.git' không có trong i [0] .split ('/')]
Roman Rdgz

Tôi muốn giới thiệu os.walk qua một vòng lặp dirlist thủ công, máy phát điện rất tuyệt, hãy sử dụng chúng.
ThorSummoner

9

Không thể bình luận để viết câu trả lời ở đây. Đây là dòng một rõ ràng nhất mà tôi đã thấy:

import os
[os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files]

4

Bạn có thể xem mẫu này tôi đã làm. Nó sử dụng chức năng os.path.walk không dùng được. Hãy sử dụng danh sách để lưu trữ tất cả các filepath

root = "Your root directory"
ex = ".txt"
where_to = "Wherever you wanna write your file to"
def fileWalker(ext,dirname,names):
    '''
    checks files in names'''
    pat = "*" + ext[0]
    for f in names:
        if fnmatch.fnmatch(f,pat):
            ext[1].append(os.path.join(dirname,f))


def writeTo(fList):

    with open(where_to,"w") as f:
        for di_r in fList:
            f.write(di_r + "\n")






if __name__ == '__main__':
    li = []
    os.path.walk(root,fileWalker,[ex,li])

    writeTo(li)

4

Một lớp lót đơn giản hơn một chút:

import os
from itertools import product, chain

chain.from_iterable([[os.sep.join(w) for w in product([i[0]], i[2])] for i in os.walk(dir)])

2

Vì mọi ví dụ ở đây chỉ là sử dụng walk(với join), tôi muốn hiển thị một ví dụ hay và so sánh với listdir:

import os, time

def listFiles1(root): # listdir
    allFiles = []; walk = [root]
    while walk:
        folder = walk.pop(0)+"/"; items = os.listdir(folder) # items = folders + files
        for i in items: i=folder+i; (walk if os.path.isdir(i) else allFiles).append(i)
    return allFiles

def listFiles2(root): # listdir/join (takes ~1.4x as long) (and uses '\\' instead)
    allFiles = []; walk = [root]
    while walk:
        folder = walk.pop(0); items = os.listdir(folder) # items = folders + files
        for i in items: i=os.path.join(folder,i); (walk if os.path.isdir(i) else allFiles).append(i)
    return allFiles

def listFiles3(root): # walk (takes ~1.5x as long)
    allFiles = []
    for folder, folders, files in os.walk(root):
        for file in files: allFiles+=[folder.replace("\\","/")+"/"+file] # folder+"\\"+file still ~1.5x
    return allFiles

def listFiles4(root): # walk/join (takes ~1.6x as long) (and uses '\\' instead)
    allFiles = []
    for folder, folders, files in os.walk(root):
        for file in files: allFiles+=[os.path.join(folder,file)]
    return allFiles


for i in range(100): files = listFiles1("src") # warm up

start = time.time()
for i in range(100): files = listFiles1("src") # listdir
print("Time taken: %.2fs"%(time.time()-start)) # 0.28s

start = time.time()
for i in range(100): files = listFiles2("src") # listdir and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.38s

start = time.time()
for i in range(100): files = listFiles3("src") # walk
print("Time taken: %.2fs"%(time.time()-start)) # 0.42s

start = time.time()
for i in range(100): files = listFiles4("src") # walk and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.47s

Vì vậy, như bạn có thể thấy cho chính mình, listdirphiên bản hiệu quả hơn nhiều. (và đó joinlà 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.