Python'da dizin ağacı listesi


Yanıtlar:


615

Bu, bir dizin ağacındaki her dosya ve dizini taramanın bir yoludur:

import os

for dirname, dirnames, filenames in os.walk('.'):
    # print path to all subdirectories first.
    for subdirname in dirnames:
        print(os.path.join(dirname, subdirname))

    # print path to all filenames.
    for filename in filenames:
        print(os.path.join(dirname, filename))

    # Advanced usage:
    # editing the 'dirnames' list will stop os.walk() from recursing into there.
    if '.git' in dirnames:
        # don't go into any .git directories.
        dirnames.remove('.git')

19
Ve bu kodu Python Kabuğundan çalıştırırsanız, Ctrl + C'nin söz konusu kabuğa çıkışı durduracağını hatırlayın. ;)
gary

41
Bu, dosyaları ve dizinleri özyinelemeli olarak listeler
rds

Hatta bazı yollar tekrarlanmasını önlemek için dirnames listesini düzenleyebilirsiniz.
bugloaf

8
@ Clément "Yukarıdan aşağı Doğru olduğunda, arayan kişi dirnames listesini yerinde değiştirebilir (belki de del veya dilim atamasını kullanarak) ve walk () yalnızca adları dizinlerde kalan alt dizinlere geri çekilir; bu, budamak için kullanılabilir arama, belirli bir ziyaret emri verme, hatta walk () işlevini tekrar aramaya başlamadan önce arayanın oluşturduğu veya yeniden adlandırdığı dizinler hakkında bilgilendirmek için. " from docs.python.org/2/library/os.html#os.walk
bugloaf

Bazı dizinleri görmezden gelmenin en kolay yolu, onları ilk etapta for subdirname in dirnames: if subdirname != '.git'
dirnamesine eklememektir

537

Kullanabilirsiniz

os.listdir(path)

Referans ve daha fazla işletim sistemi işlevi için buraya bakın:


1
orijinal soru özyinelemeli bir çözüm isteyip istemediklerini bilmeyecek kadar belirsiz. "bir dizindeki tüm dosyalar" özyinelemeli olarak yorumlanabilir.
Tommy

3
@Tommy, bir "dizin" açıkça tanımlanmış bir veri yapısı ve "ls -R" yerine "ls" anlamına gelir. Ayrıca, hemen hemen tüm UNIX araçları varsayılan olarak yinelemeli olarak çalışmaz. Sorgulayıcının ne anlama geldiğini bilmiyorum ama yazdığı şey açıktı.
Torsten Bronger

os.scandirBununla birlikte, python 3 belgeleri bunun yerine kullanmanızı söyler , çünkü çoğu durumda sistem çağrılarını önlemenize izin verir, ücretsiz bir hızlanma sağlar (hem IPC hem de IO yavaştır).
Jappie Kerk

5
listdir size dizindeki tek dosya adını verir, tam yolu almak için kullanılabilecek bir yöntem var mı?
greperror

1
@greperror Tam yolu almak için os.path.abspath komutunu kullanabilirsiniz . Ayrıca, belirli bir yolun bir dosya olup olmadığını denetlemek için os.path.isfile veya öğesini kullanın os.path.isdir.
Aleksandar

111

İşte oldukça sık kullandığım bir yardımcı fonksiyon:

import os

def listdir_fullpath(d):
    return [os.path.join(d, f) for f in os.listdir(d)]

3
Bir jeneratör daha iyi olurdu.
Robert Siemer

1
@RobertSiemer kullanıma bağlıdır. Çoğu durumda, bir liste daha iyi olurdu, ancak bir listeye dönüştürülebildiğinden bir jeneratörün daha çok yönlü olduğunu düşünüyorum. Bu, aradığınıza, çok yönlülüğe veya biraz daha aerodinamik bir şeye bağlıdır.
James Mchugh

3
On yıl oldu, ama sanırım bu şekilde yaptım çünkü os.listdir () bir liste döndürüyor ve bunu taklit ediyordum.
giltay

82
import os

for filename in os.listdir("C:\\temp"):
    print  filename

16
r'C:\temp'daha açıktır ve "C:\\temp"Rawstrings tercih edilir ters eğik çizgi escpaing tercih edilir.
smci

13

Globbing yeteneklerine ihtiyacınız varsa, bunun için de bir modül var. Örneğin:

import glob
glob.glob('./[0-9].*')

gibi bir şey döndürür:

['./1.gif', './2.txt']

Buradaki belgelere bakın .


10

Bunu dene:

import os
for top, dirs, files in os.walk('./'):
    for nm in files:       
        print os.path.join(top, nm)

Bir satırda: [top için üst + os.sep + f, dosyalarda f için os.walk ('./') içindeki dosyalar]
J. Peterson

9

Geçerli çalışma dizinindeki bir yol belirtmeden dosyalar için

Python 2.7:

import os
os.listdir(os.getcwd())

Python 3.x:

import os
os.listdir()

Stayt Kaly'e python 3.x hakkındaki yorum için teşekkürler


5
os.listdir()Geçerli dizindeki öğeleri varsayılan olarak listeler! Yani gerek yok os.getcwd():)
Stam Kaly

Bunu nasıl yaparım? Ben argüman olmadan >>> os.listdir () kullandığımda: TypeError: listdir () tam olarak 1 argüman alır (0 verilir)
Dave Engineer

2
Sanırım 2.7. Bu, 3.x'te eklendi
Stam Kaly

5

Özyinelemeli uygulama

import os

def scan_dir(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            print path
        else:
            scan_dir(path)

3

İhtiyacım olan tüm seçeneklerle uzun bir versiyon yazdım: http://sam.nipl.net/code/python/find.py

Sanırım buraya da sığacak:

#!/usr/bin/env python

import os
import sys

def ls(dir, hidden=False, relative=True):
    nodes = []
    for nm in os.listdir(dir):
        if not hidden and nm.startswith('.'):
            continue
        if not relative:
            nm = os.path.join(dir, nm)
        nodes.append(nm)
    nodes.sort()
    return nodes

def find(root, files=True, dirs=False, hidden=False, relative=True, topdown=True):
    root = os.path.join(root, '')  # add slash if not there
    for parent, ldirs, lfiles in os.walk(root, topdown=topdown):
        if relative:
            parent = parent[len(root):]
        if dirs and parent:
            yield os.path.join(parent, '')
        if not hidden:
            lfiles   = [nm for nm in lfiles if not nm.startswith('.')]
            ldirs[:] = [nm for nm in ldirs  if not nm.startswith('.')]  # in place
        if files:
            lfiles.sort()
            for nm in lfiles:
                nm = os.path.join(parent, nm)
                yield nm

def test(root):
    print "* directory listing, with hidden files:"
    print ls(root, hidden=True)
    print
    print "* recursive listing, with dirs, but no hidden files:"
    for f in find(root, dirs=True):
        print f
    print

if __name__ == "__main__":
    test(*sys.argv[1:])

3

İşte başka bir seçenek.

os.scandir(path='.')

Yol tarafından verilen dizindeki girdilere (dosya öznitelik bilgileriyle birlikte) karşılık gelen os.DirEntry nesnelerinin yinelemesini döndürür.

Misal:

with os.scandir(path) as it:
    for entry in it:
        if not entry.name.startswith('.'):
            print(entry.name)

ListDel () yerine scandir () kullanılması, dosya türü veya dosya özniteliği bilgileri de gerektiren kod performansını önemli ölçüde artırabilir , çünkü işletim sistemi bir dizini tararken işletim sistemi tarafından sağlanıyorsa os.DirEntry nesneleri bu bilgileri ortaya çıkarır. Tüm os.DirEntry yöntemleri bir sistem çağrısı gerçekleştirebilir, ancak is_dir () ve is_file () genellikle sembolik bağlantılar için yalnızca bir sistem çağrısı gerektirir; os.DirEntry.stat () her zaman Unix üzerinde sistem çağrısı gerektirir, ancak Windows'taki sembolik bağlantılar için yalnızca bir çağrı gerektirir.

Python Dokümanları


3

os.listdir()Dosya ve dizin adlarının bir listesini oluşturmak için iyi olsa da, genellikle bu adlara sahip olduğunuzda daha fazlasını yapmak istersiniz - ve Python3'te, pathlib bu diğer işleri kolaylaştırır. Bir göz atalım ve benim kadar beğendin mi bakalım.

Dizin içeriğini listelemek için bir Path nesnesi oluşturun ve yineleyiciyi alın:

In [16]: Path('/etc').iterdir()
Out[16]: <generator object Path.iterdir at 0x110853fc0>

Sadece şeylerin isimlerinin bir listesini istiyorsak:

In [17]: [x.name for x in Path('/etc').iterdir()]
Out[17]:
['emond.d',
 'ntp-restrict.conf',
 'periodic',

Sadece dirs istiyorsanız:

In [18]: [x.name for x in Path('/etc').iterdir() if x.is_dir()]
Out[18]:
['emond.d',
 'periodic',
 'mach_init.d',

Bu ağaçtaki tüm conf dosyalarının adlarını istiyorsanız:

In [20]: [x.name for x in Path('/etc').glob('**/*.conf')]
Out[20]:
['ntp-restrict.conf',
 'dnsextd.conf',
 'syslog.conf',

Ağaçtaki conf dosyalarının bir listesini istiyorsanız = = 1K:

In [23]: [x.name for x in Path('/etc').glob('**/*.conf') if x.stat().st_size > 1024]
Out[23]:
['dnsextd.conf',
 'pf.conf',
 'autofs.conf',

Göreli yolları çözmek kolaylaşır:

In [32]: Path('../Operational Metrics.md').resolve()
Out[32]: PosixPath('/Users/starver/code/xxxx/Operational Metrics.md')

Bir Yol ile navigasyon oldukça açıktır (beklenmedik olsa da):

In [10]: p = Path('.')

In [11]: core = p / 'web' / 'core'

In [13]: [x for x in core.iterdir() if x.is_file()]
Out[13]:
[PosixPath('web/core/metrics.py'),
 PosixPath('web/core/services.py'),
 PosixPath('web/core/querysets.py'),

1

Sadece dosyaları özyinelemeli olarak listelemek için güzel bir astar. Bunu setup.py package_data yönergesimde kullandım:

import os

[os.path.join(x[0],y) for x in os.walk('<some_directory>') for y in x[2]]

Sorunun cevabı olmadığını biliyorum, ama işe yarayabilir


1

Python 2 için

#!/bin/python2

import os

def scan_dir(path):
    print map(os.path.abspath, os.listdir(pwd))

Python 3 için

Filtre ve harita için bunları listeyle sarmanız gerekir ()

#!/bin/python3

import os

def scan_dir(path):
    print(list(map(os.path.abspath, os.listdir(pwd))))

Şimdi öneri, harita ve filtre kullanımınızı jeneratör ifadeleri veya liste kavrayışlarıyla değiştirmenizdir:

#!/bin/python

import os

def scan_dir(path):
    print([os.path.abspath(f) for f in os.listdir(path)])

1

İşte bir satır Pythonic versiyonu:

import os
dir = 'given_directory_name'
filenames = [os.path.join(os.path.dirname(os.path.abspath(__file__)),dir,i) for i in os.listdir(dir)]

Bu kod, verilen dizin adındaki tüm dosya ve dizinlerin tam yolunu listeler.


Teşekkürler Saleh, ancak kodunuz tam olarak çalışmadı ve çalışılan kod şu şekilde değiştirildi: i için 'dir =' given_directory_name 'dosyaadı = [os.path.abspath (os.path.join (dir, i)) os.listdir (dir)] '
HassanSh__3571619

1

Bunun eski bir soru olduğunu biliyorum. Bir liunx makinesindeyseniz, bu düzgün bir şekilde karşılaştım.

import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))

0
#import modules
import os

_CURRENT_DIR = '.'


def rec_tree_traverse(curr_dir, indent):
    "recurcive function to traverse the directory"
    #print "[traverse_tree]"

    try :
        dfList = [os.path.join(curr_dir, f_or_d) for f_or_d in os.listdir(curr_dir)]
    except:
        print "wrong path name/directory name"
        return

    for file_or_dir in dfList:

        if os.path.isdir(file_or_dir):
            #print "dir  : ",
            print indent, file_or_dir,"\\"
            rec_tree_traverse(file_or_dir, indent*2)

        if os.path.isfile(file_or_dir):
            #print "file : ",
            print indent, file_or_dir

    #end if for loop
#end of traverse_tree()

def main():

    base_dir = _CURRENT_DIR

    rec_tree_traverse(base_dir," ")

    raw_input("enter any key to exit....")
#end of main()


if __name__ == '__main__':
    main()

5
Bu sorunun zaten oldukça iyi bir cevabı var, tekrar cevaplamaya gerek yok
Mike Pennington

0

FYI Bir uzantı veya ext dosyası içe aktarma os filtresi ekle

path = '.'
for dirname, dirnames, filenames in os.walk(path):
    # print path to all filenames with extension py.
    for filename in filenames:
        fname_path = os.path.join(dirname, filename)
        fext = os.path.splitext(fname_path)[1]
        if fext == '.py':
            print fname_path
        else:
            continue

0

Eğer anladıysam bunu fırlatırdım. Joker karakter araması yapmanın basit ve kirli yolu.

import re
import os

[a for a in os.listdir(".") if re.search("^.*\.py$",a)]

0

Aşağıdaki kod, dizinleri ve dizin içindeki dosyaları listeler

def print_directory_contents(sPath):
        import os                                       
        for sChild in os.listdir(sPath):                
            sChildPath = os.path.join(sPath,sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)

0

Benimle çalışan biri yukarıdaki Saleh cevabından değiştirilmiş bir versiyon.

Kod aşağıdaki gibidir:

"dir = 'given_directory_name' dosyaadı = [os.listdir (dir)] içindeki i için os.path.abspath (os.path.join (dir, i))" "

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.