Listado de árbol de directorios en Python

Respuestas:

615

Esta es una manera de recorrer cada archivo y directorio en un árbol de directorios:

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
fuente
19
Y si ejecuta este código (como está) desde Python Shell, recuerde que Ctrl + C detendrá la salida a dicho shell. ;)
Gary
41
Esto enumerará recursivamente archivos y directorios
rds
Incluso puede editar la lista de nombres de directorio para evitar que se repita en algunas rutas.
bugloaf
8
@ Clément "Cuando el topdown es True, la persona que llama puede modificar la lista de nombres de directorio en el lugar (tal vez usando la asignación del o slice), y walk () solo volverá a aparecer en los subdirectorios cuyos nombres permanecen en los nombres de directorio; esto se puede usar para podar buscar, imponer un orden específico de visitas o incluso informar a walk () sobre los directorios que la persona que llama crea o renombra antes de que reanude walk () nuevamente ". de docs.python.org/2/library/os.html#os.walk
bugloaf
La forma más sencilla de ignorar algunos directorios es no agregarlos a los nombres de directorio en primer lugarfor subdirname in dirnames: if subdirname != '.git'
smci
537

Puedes usar

os.listdir(path)

Para referencia y más funciones del sistema operativo, mira aquí:

rslite
fuente
1
bueno, la pregunta original es lo suficientemente vaga como para no saber si querían una solución recursiva. "todos los archivos en un directorio" podrían interpretarse como recursivos.
Tommy
3
@Tommy, un "directorio" es una estructura de datos claramente definida, y se refiere a "ls" en lugar de "ls -R". Además, casi todas las herramientas UNIX no funcionan de forma recursiva por defecto. No sé a qué se refería el interrogador, pero lo que escribió fue claro.
Torsten Bronger
os.scandirSin embargo, los documentos de Python 3 le indican que debe usarlo , ya que en muchos casos le permite evitar llamadas al sistema, lo que proporciona una aceleración gratuita (tanto IPC como IO son lentos).
Jappie Kerk
55
listdir le da el único nombre de archivo en el directorio, ¿hay algún método disponible para obtener la ruta completa?
greperror
1
@greperror Puede usar os.path.abspath para obtener la ruta completa. Además, para comprobar si una ruta determinada es un archivo, use el archivo os.path.is o os.path.isdir.
Aleksandar
112

Aquí hay una función auxiliar que uso con bastante frecuencia:

import os

def listdir_fullpath(d):
    return [os.path.join(d, f) for f in os.listdir(d)]
Giltay
fuente
3
Un generador sería mejor.
Robert Siemer
1
@RobertSiemer que depende del uso. En muchos casos, una lista sería mejor, pero supongo que un generador es más versátil ya que puede convertirse en una lista. Depende de si estás buscando, versatilidad o algo un poco más aerodinámico.
James Mchugh
44
Han pasado diez años, pero creo que lo hice de esta manera porque os.listdir () devuelve una lista y lo estaba imitando.
giltay
82
import os

for filename in os.listdir("C:\\temp"):
    print  filename
curtisk
fuente
16
r'C:\temp'es más claro y preferido que los "C:\\temp"Rawstrings son preferibles a esclasar las barras invertidas.
smci
13

Si necesita habilidades de globbing, también hay un módulo para eso. Por ejemplo:

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

devolverá algo como:

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

Vea la documentación aquí .

kenny
fuente
10

Prueba esto:

import os
for top, dirs, files in os.walk('./'):
    for nm in files:       
        print os.path.join(top, nm)
paxdiablo
fuente
En una línea: [top + os.sep + f para top, dirs, archivos en os.walk ('./') para f en archivos]
J. Peterson
9

Para archivos en el directorio de trabajo actual sin especificar una ruta

Python 2.7:

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

Python 3.x:

import os
os.listdir()

Gracias a Stam Kaly por comentar sobre python 3.x

Dave Engineer
fuente
55
os.listdir()¡enumera elementos en el directorio actual por defecto! Así que no hay necesidad de os.getcwd():)
Stam Kaly
¿Cómo haría esto? Cuando uso >>> os.listdir () sin argumento obtengo: TypeError: listdir () toma exactamente 1 argumento (0 dado)
Dave Engineer
2
Supongo que estás ejecutando en 2.7. Esto se agregó en 3.x
Stam Kaly
5

Una implementación recursiva

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
fuente
3

Escribí una versión larga, con todas las opciones que podría necesitar: http://sam.nipl.net/code/python/find.py

Supongo que también encajará aquí:

#!/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
fuente
3

Aquí hay otra opción.

os.scandir(path='.')

Devuelve un iterador de objetos os.DirEntry correspondientes a las entradas (junto con la información del atributo del archivo) en el directorio proporcionado por la ruta.

Ejemplo:

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

El uso de scandir () en lugar de listdir () puede aumentar significativamente el rendimiento del código que también necesita información de tipo de archivo o atributo de archivo , porque los objetos os.DirEntry exponen esta información si el sistema operativo la proporciona al escanear un directorio. Todos los métodos os.DirEntry pueden realizar una llamada al sistema, pero is_dir () y is_file () generalmente solo requieren una llamada al sistema para enlaces simbólicos; os.DirEntry.stat () siempre requiere una llamada al sistema en Unix, pero solo requiere una para enlaces simbólicos en Windows.

Documentos de Python

Khaino
fuente
3

Si os.listdir()bien está bien para generar una lista de nombres de archivos y directorios, con frecuencia desea hacer más una vez que tenga esos nombres, y en Python3, pathlib simplifica esas otras tareas. Echemos un vistazo y veamos si te gusta tanto como a mí.

Para enumerar el contenido del directorio, construya un objeto Path y tome el iterador:

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

Si queremos solo una lista de nombres de cosas:

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

Si solo quieres los directorios:

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

Si desea los nombres de todos los archivos conf en ese árbol:

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

Si desea una lista de archivos conf en el árbol> = 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',

Resolver rutas relativas se vuelve fácil:

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

Navegar con una ruta es bastante claro (aunque inesperado):

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
fuente
1

Un buen revestimiento para enumerar solo los archivos de forma recursiva. Lo utilicé en mi directiva setup.py package_data:

import os

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

Sé que no es la respuesta a la pregunta, pero puede ser útil.

Fivetentaylor
fuente
1

Para Python 2

#!/bin/python2

import os

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

Para Python 3

Para el filtro y el mapa, debe envolverlos con list ()

#!/bin/python3

import os

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

La recomendación ahora es que reemplace su uso de mapas y filtros con expresiones de generadores o comprensiones de listas:

#!/bin/python

import os

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

Aquí hay una versión Pythonic de una línea:

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

Este código enumera la ruta completa de todos los archivos y directorios en el nombre de directorio dado.

Salehinejad
fuente
Gracias Saleh, pero su código no funcionó por completo, y el que funcionó se modificó de la siguiente manera: 'dir =' nombre_directorio_denominado 'nombres de archivo = [os.path.abspath (os.path.join (dir, i)) para i en os.listdir (dir)] '
HassanSh__3571619
1

Sé que esta es una vieja pregunta. Esta es una buena manera de encontrarme si estás en una máquina liunx.

import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))
apeter
fuente
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
fuente
55
Esta pregunta ya tiene una respuesta perfectamente buena, no hay necesidad de responder de nuevo
Mike Pennington el
0

FYI Agregue un filtro de extensión o archivo de importación import os

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
fuente
0

Si supiera que tiraría esto. Una forma simple y sucia de hacer búsquedas con comodines.

import re
import os

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

El siguiente código enumerará los directorios y los archivos dentro del directorio

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
fuente
0

El que trabajó conmigo es una especie de versión modificada de la respuesta de Saleh anterior.

El código es el siguiente:

"dir = 'given_directory_name' nombres de archivo = [os.path.abspath (os.path.join (dir, i)) para i en os.listdir (dir)]"

HassanSh__3571619
fuente