Python liste dizini, alt dizin ve dosyalar


130

Belirli bir dizindeki tüm dizini, alt dizini ve dosyaları listelemek için bir komut dosyası oluşturmaya çalışıyorum.
Bunu denedim:

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)

Ne yazık ki düzgün çalışmıyor.
Tüm dosyaları alıyorum, ancak tam yollarını almıyorum.

Örneğin, dir struct şöyle olursa:

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

Yazdırır:

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

İhtiyacım olan şey ilk sonuç. Herhangi bir yardım çok takdir edilecektir! Teşekkürler.

Yanıtlar:


225

Dizini ve dosya adınıos.path.join birleştirmek için kullanın :

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

Kullanım yanlış olacağından , birleştirmede pathdeğil kullanımına dikkat rootedin root.


Python 3.4'te, daha kolay yol manipülasyonları için pathlib modülü eklenmiştir. Öyleyse eşdeğeri os.path.joinşöyle olacaktır:

pathlib.PurePath(path, name)

Bunun avantajı pathlib, yollar üzerinde çeşitli yararlı yöntemler kullanabilmenizdir. Somut Pathvaryantı kullanırsanız, bunlar aracılığıyla bir dizine geçmek, yolu silmek, işaret ettiği dosyayı açmak ve çok daha fazlası gibi gerçek işletim sistemi çağrıları da yapabilirsiniz.


bu, "tüm dosyaların python'da özyinelemeli olarak nasıl elde edileceği" ile ilgili olarak sorulan birçok soru için tek ve yararlı cevaptır.
harrisonfooord

anlama listesi: all_files = [yol, alt dizinler, os.walk'taki dosyalar (klasör) içindeki dosyalar için os.path.join (yol, ad)]
Nir

Python3'te yazdırma işlevi için parantez kullanınprint(os.path.join(path, name))
Ehsan

45

Her ihtimale karşı ... Dizindeki ve alt dizinlerdeki bazı kalıplarla eşleşen tüm dosyalar alınıyor (örneğin * .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

İşte tek satırlık:

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

En dıştaki val for sublist in ...döngü listeyi tek boyutlu olacak şekilde düzleştirir. jDöngü her dosya basename bir listesini toplar ve geçerli yolu onu katılır. Son olarak, idöngü tüm dizinleri ve alt dizinleri yineler.

Bu örnek ./, os.walk(...)çağrıda sabit kodlanmış yolu kullanır , istediğiniz herhangi bir yol dizesini tamamlayabilirsiniz.

Not: os.path.expanduserve / veya os.path.expandvarsgibi yol dizeleri için kullanılabilir~/

Bu örneği genişletmek için:

Dosya taban adı testleri ve yönetici adı testleri eklemek kolaydır.

Örneğin, *.jpgdosyaları test etme :

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

Ek olarak, .gitdizini hariç tutarak :

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

İşe yarıyor, ancak .git dizinini dışlamak için, '.git'in yolun içinde OLMADIĞINI kontrol etmeniz gerekir.
Roman Rdgz

Evet. '.Git' i [0] .split ('/') içinde
değilse olmalıdır

os.walkManuel bir yönlendirme döngüsü üzerinden tavsiye ederim , jeneratörler harika, gidin onları kullanın.
ThorSummoner

9

Yorum yapamadım, bu yüzden burada cevap yazıyorum. Bu gördüğüm en net tek satır:

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

4

Yaptığım bu örneğe bir göz atabilirsiniz. Kullanımdan kaldırılan os.path.walk işlevini kullanır. Tüm dosya yollarını saklamak için bir liste kullanır.

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

Biraz daha basit tek satırlık:

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

Buradaki her örnek sadece walk(with join) kullandığından, güzel bir örnek göstermek ve şununla karşılaştırma yapmak istiyorum 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

Dolayısıyla, kendiniz de görebileceğiniz gibi, listdirsürüm çok daha verimli. (ve bu joinyavaş)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.