rutas - Archivos recursivos de búsqueda y devolución de subcarpetas en una lista de python
recorrer directorios en python (5)
Modificado en Python 3.5 : Soporte para globs recursivos usando "**".
glob.glob()
obtuvo un nuevo parámetro recursivo .
Si desea obtener cada archivo .txt
en my_path
(recursivamente incluyendo subdirectorios):
import glob
files = glob.glob(my_path + ''/**/*.txt'', recursive=True)
# my_path/ the dir
# **/ every file and dir under my_path
# *.txt every file that ends with ''.txt''
Si necesita un iterador, puede usar iglob como alternativa:
for file in glob.iglob(my_path, recursive=False):
# ...
Estoy trabajando en un script para examinar recursivamente subcarpetas en una carpeta principal y crear una lista de un cierto tipo de archivo. Tengo un problema con el guión. Su configuración actual es la siguiente
for root, subFolder, files in os.walk(PATH):
for item in files:
if item.endswith(".txt") :
fileNamePath = str(os.path.join(root,subFolder,item))
el problema es que la variable subFolder está tirando de una lista de subcarpetas en lugar de la carpeta en la que se encuentra el archivo ITEM. Estaba pensando en ejecutar un bucle for para la subcarpeta antes y unirme a la primera parte de la ruta pero pensé que debería verificar si alguien tiene alguna sugerencia antes de eso. ¡Gracias por tu ayuda!
Debería usar el dirpath
que llama root
. Los dirnames
se suministran para que pueda podarlos si hay carpetas en las que no desea que os.walk
.
import os
result = [os.path.join(dp, f) for dp, dn, filenames in os.walk(PATH) for f in filenames if os.path.splitext(f)[1] == ''.txt'']
Editar:
Después del último downvote, se me ocurrió que glob
es una mejor herramienta para seleccionar por extensión.
import os
from glob import glob
result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], ''*.txt''))]
También una versión de generador
from itertools import chain
result = (chain.from_iterable(glob(os.path.join(x[0], ''*.txt'')) for x in os.walk(''.'')))
La nueva biblioteca pathlib
simplifica esto en una línea:
from pathlib import Path
result = list(Path(PATH).glob(''**/*.txt''))
También puede usar la versión del generador:
from pathlib import Path
for file in Path(PATH).glob(''**/*.txt''):
pass
Esto devuelve objetos de Path
, que puede usar prácticamente para cualquier cosa u obtener el nombre del archivo como una cadena por nombre de archivo.
No es la respuesta más pitonica, pero la pondré aquí para divertirme porque es una buena lección en recursión
def find_files( files, dirs=[], extensions=[]):
new_dirs = []
for d in dirs:
try:
new_dirs += [ os.path.join(d, f) for f in os.listdir(d) ]
except OSError:
if os.path.splitext(d)[1] in extensions:
files.append(d)
if new_dirs:
find_files(files, new_dirs, extensions )
else:
return
En mi máquina tengo dos carpetas, root
y root2
mender@multivax ]ls -R root root2
root:
temp1 temp2
root/temp1:
temp1.1 temp1.2
root/temp1/temp1.1:
f1.mid
root/temp1/temp1.2:
f.mi f.mid
root/temp2:
tmp.mid
root2:
dummie.txt temp3
root2/temp3:
song.mid
Digamos que quiero encontrar todos los archivos .txt
y todos los .mid
en cualquiera de estos directorios, entonces puedo simplemente hacer
files = []
find_files( files, dirs=[''root'',''root2''], extensions=[''.mid'',''.txt''] )
print(files)
#[''root2/dummie.txt'',
# ''root/temp2/tmp.mid'',
# ''root2/temp3/song.mid'',
# ''root/temp1/temp1.1/f1.mid'',
# ''root/temp1/temp1.2/f.mid'']
Voy a traducir la comprensión de la lista de John La Rooy a anidados, por si acaso alguien tiene problemas para entenderla.
result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], ''*.txt''))]
Debería ser equivalente a:
result = []
for x in os.walk(PATH):
for y in glob(os.path.join(x[0], ''*.txt'')):
result_for.append(y)
Aquí está la documentación para la comprensión de la lista y las funciones os.walk y glob.glob .