Liste de l'arborescence des répertoires en Python

Réponses:

615

C'est un moyen de parcourir chaque fichier et répertoire dans une arborescence de répertoires:

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')
Jerub
la source
19
Et si vous exécutez ce code (tel quel) à partir du shell Python, rappelez-vous que Ctrl + C arrêtera la sortie vers ledit shell. ;)
gary
41
Ceci
listera
Vous pouvez même modifier la liste des noms de répertoires pour l'empêcher de se reproduire sur certains chemins.
bugloaf
8
@ Clément "Lorsque topdown est True, l'appelant peut modifier la liste des noms de répertoires sur place (peut-être en utilisant l'affectation del ou slice), et walk () ne récursera que dans les sous-répertoires dont les noms restent dans les noms de répertoires; cela peut être utilisé pour élaguer le rechercher, imposer un ordre de visite spécifique ou même informer walk () des répertoires que l'appelant crée ou renomme avant de reprendre walk (). " de docs.python.org/2/library/os.html#os.walk
bugloaf
La manière la plus simple d'ignorer certains répertoires est de ne pas les ajouter aux répertoires en premier lieufor subdirname in dirnames: if subdirname != '.git'
smci
537

Vous pouvez utiliser

os.listdir(path)

Pour référence et plus de fonctions os, regardez ici:

rslite
la source
1
eh bien la question d'origine est juste assez vague pour ne pas savoir s'ils voulaient une solution récursive. "tous les fichiers d'un répertoire" peuvent être interprétés comme récursifs.
Tommy
3
@Tommy, un «répertoire» est une structure de données clairement définie, et il fait référence à «ls» plutôt qu'à «ls -R». De plus, presque tous les outils UNIX ne fonctionnent pas récursivement par défaut. Je ne sais pas ce que le questionneur voulait dire, mais ce qu'il a écrit était clair.
Torsten Bronger
Les documents de python 3 vous disent os.scandircependant d'utiliser à la place, car dans de nombreux cas, cela vous permet d'empêcher les appels système, ce qui donne une accélération gratuite (IPC et IO sont lents).
Jappie Kerk
5
listdir vous donne le seul nom de fichier dans le répertoire, y a-t-il une méthode disponible pour obtenir le chemin complet?
greperror
1
@greperror Vous pouvez utiliser os.path.abspath pour obtenir le chemin complet. De plus, pour vérifier si un chemin donné est un fichier, utilisez os.path.isfile ou os.path.isdir.
Aleksandar
112

Voici une fonction d'aide que j'utilise assez souvent:

import os

def listdir_fullpath(d):
    return [os.path.join(d, f) for f in os.listdir(d)]
giltay
la source
3
Un générateur serait mieux.
Robert Siemer
1
@RobertSiemer qui dépend de l'utilisation. Dans de nombreux cas, une liste serait mieux, mais je suppose qu'un générateur est plus polyvalent car il peut être converti en liste. Cela dépend si vous recherchez, la polyvalence ou quelque chose d'un peu plus rationalisé.
James Mchugh
4
Cela fait dix ans, mais je pense que je l'ai fait de cette façon parce que os.listdir () renvoie une liste et j'imitais cela.
giltay
82
import os

for filename in os.listdir("C:\\temp"):
    print  filename
Curtisk
la source
16
r'C:\temp'est plus clair et préféré à "C:\\temp"Rawstrings sont préférables aux barres obliques inverses.
smci
13

Si vous avez besoin de capacités globbing, il existe également un module pour cela. Par exemple:

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

renverra quelque chose comme:

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

Voir la documentation ici .

kenny
la source
10

Essaye ça:

import os
for top, dirs, files in os.walk('./'):
    for nm in files:       
        print os.path.join(top, nm)
paxdiablo
la source
En une ligne: [top + os.sep + f pour top, dirs, fichiers dans os.walk ('./') pour f dans les fichiers]
J. Peterson
9

Pour les fichiers dans le répertoire de travail actuel sans spécifier de chemin

Python 2.7:

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

Python 3.x:

import os
os.listdir()

Merci à Stam Kaly pour ses commentaires sur python 3.x

Dave Engineer
la source
5
os.listdir()liste les éléments du répertoire courant par défaut! Donc pas besoin de os.getcwd():)
Stam Kaly
Comment pourrais-je faire ça? Lorsque j'utilise >>> os.listdir () sans argument, j'obtiens: TypeError: listdir () prend exactement 1 argument (0 donné)
Dave Engineer
2
Je suppose que vous utilisez 2.7. Ceci a été ajouté le 3.x
Stam Kaly
5

Une implémentation récursive

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)
Arnaldo P. Figueira Figueira
la source
3

J'ai écrit une version longue, avec toutes les options dont j'ai besoin: http://sam.nipl.net/code/python/find.py

Je suppose que ça ira ici aussi:

#!/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:])
Sam Watkins
la source
3

Voici une autre option.

os.scandir(path='.')

Il renvoie un itérateur d'objets os.DirEntry correspondant aux entrées (ainsi que les informations d'attribut de fichier) dans le répertoire donné par path.

Exemple:

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

L'utilisation de scandir () au lieu de listdir () peut augmenter considérablement les performances du code qui nécessite également des informations sur le type ou l'attribut de fichier , car les objets os.DirEntry exposent ces informations si le système d'exploitation les fournit lors de l'analyse d'un répertoire. Toutes les méthodes os.DirEntry peuvent effectuer un appel système, mais is_dir () et is_file () nécessitent généralement un appel système uniquement pour les liens symboliques; os.DirEntry.stat () nécessite toujours un appel système sous Unix mais n'en requiert qu'un pour les liens symboliques sous Windows.

Documents Python

Khaino
la source
3

Bien que ce os.listdir()soit bien pour générer une liste de noms de fichiers et de répertoires, vous voulez souvent en faire plus une fois que vous avez ces noms - et en Python3, pathlib simplifie ces autres tâches. Jetons un coup d'œil et voyons si vous l'aimez autant que moi.

Pour lister le contenu du répertoire, construisez un objet Path et récupérez l'itérateur:

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

Si nous voulons juste une liste de noms de choses:

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

Si vous voulez juste les dirs:

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

Si vous voulez les noms de tous les fichiers conf dans cette arborescence:

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

Si vous voulez une liste de fichiers conf dans l'arborescence> = 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',

La résolution des chemins relatifs devient facile:

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

Naviguer avec un chemin est assez clair (bien qu'inattendu):

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'),
Steve Tarver
la source
1

Une belle doublure pour ne lister que les fichiers récursivement. J'ai utilisé ceci dans ma directive package_data setup.py:

import os

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

Je sais que ce n'est pas la réponse à la question, mais peut être utile

fivetentaylor
la source
1

Pour Python 2

#!/bin/python2

import os

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

Pour Python 3

Pour le filtre et la carte, vous devez les envelopper avec list ()

#!/bin/python3

import os

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

La recommandation est maintenant de remplacer votre utilisation de la carte et du filtre par des expressions de générateurs ou des compréhensions de liste:

#!/bin/python

import os

def scan_dir(path):
    print([os.path.abspath(f) for f in os.listdir(path)])
Alejandro Blasco
la source
1

Voici une version Pythonic d'une ligne:

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)]

Ce code répertorie le chemin d'accès complet de tous les fichiers et répertoires dans le nom de répertoire donné.

salehinejad
la source
Merci Saleh, mais votre code n'a pas fonctionné complètement, et celui qui a fonctionné a été modifié comme suit: 'dir =' given_directory_name 'filenames = [os.path.abspath (os.path.join (dir, i)) for i in os.listdir (dir)] '
HassanSh__3571619
1

Je sais que c'est une vieille question. C'est une bonne façon de voir si vous êtes sur une machine liunx.

import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))
apeter
la source
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()
Alok
la source
5
Cette question a déjà une réponse parfaitement bonne, il n'est pas nécessaire d'y répondre à nouveau
Mike Pennington
0

FYI Ajouter un filtre d'os d'importation d'extensions ou de fichiers ext

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
moylop260
la source
0

Si figuré, je jetterais cela. Un moyen simple et sale de faire des recherches génériques.

import re
import os

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

Le code ci-dessous répertorie les répertoires et les fichiers dans le répertoire

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)
Heenashree Khandelwal
la source
0

Celui qui a travaillé avec moi est une sorte de version modifiée de la réponse Saleh ci-dessus.

Le code est comme suit:

"dir = 'given_directory_name' filenames = [os.path.abspath (os.path.join (dir, i)) pour i dans os.listdir (dir)]"

HassanSh__3571619
la source