ver una recorrer partir lista ficheros directorio crear con carpetas carpeta archivos abrir python filesystems wildcard glob directory-listing

una - python recorrer ficheros directorio



Obtener una lista filtrada de archivos en un directorio (10)

Estoy tratando de obtener una lista de archivos en un directorio usando Python, pero no quiero una lista de TODOS los archivos.

Lo que esencialmente quiero es la capacidad de hacer algo como lo siguiente pero usando Python y no ejecutando ls.

ls 145592*.jpg

Si no hay un método incorporado para esto, actualmente estoy pensando en escribir un ciclo for para recorrer los resultados de un os.listdir() y agregar todos los archivos coincidentes a una nueva lista.

Sin embargo, hay muchos archivos en ese directorio y, por lo tanto, espero que haya un método más eficiente (o un método incorporado).


Mantenlo simple:

import os relevant_path = "[path to folder]" included_extenstions = [''jpg'', ''bmp'', ''png'', ''gif''] file_names = [fn for fn in os.listdir(relevant_path) if any(fn.endswith(ext) for ext in included_extensions)]

Prefiero esta forma de comprensión de listas porque se lee bien en inglés.

Leí la cuarta línea como: por cada fn en os.listdir de mi ruta, proporcióneme solo los que coincidan con alguna de mis extensiones incluidas.

Puede ser difícil para los programadores de Python principiantes acostumbrarse a usar listas de comprensión para el filtrado, y puede tener cierta sobrecarga de memoria para conjuntos de datos muy grandes, pero para enumerar un directorio y otras tareas sencillas de filtrado de cadenas, las listas de comprensión conducen a una mayor limpieza código documentable.

Lo único sobre este diseño es que no lo protege contra el error de pasar una cadena en lugar de una lista. Por ejemplo, si conviertes accidentalmente una cadena en una lista y terminas controlando todos los caracteres de una cadena, podrías terminar recibiendo una gran cantidad de falsos positivos.

Pero es mejor tener un problema que sea fácil de solucionar que una solución que es difícil de entender.


Nombres de archivos con extensiones "jpg" y "png" en "ruta / a / imágenes":

import os accepted_extensions = ["jpg", "png"] filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]



Puede usar subprocess.check_ouput () como

import subprocess list_files = subprocess.check_output("ls 145992*.jpg", shell=True)

Por supuesto, la cadena entre comillas puede ser cualquier cosa que desee ejecutar en el shell, y almacenar la salida.


es posible que también desee un enfoque de más alto nivel (lo he implementado y empaquetado como herramientas de búsqueda ):

from findtools.find_files import (find_files, Match) # Recursively find all *.txt files in **/home/** txt_files_pattern = Match(filetype=''f'', name=''*.txt'') found_files = find_files(path=''/home'', match=txt_files_pattern) for found_file in found_files: print found_file

se puede instalar con

pip install findtools


utilice os.walk para enumerar recursivamente sus archivos

import os root = "/home" pattern = "145992" alist_filter = [''jpg'',''bmp'',''png'',''gif''] path=os.path.join(root,"mydir_to_scan") for r,d,f in os.walk(path): for file in f: if file[-3:] in alist_filter and pattern in file: print os.path.join(root,file)



glob.glob() es definitivamente la manera de hacerlo (según Ignacio). Sin embargo, si necesita una coincidencia más complicada, puede hacerlo con una lista de comprensión y re.match() , algo así:

files = [f for f in os.listdir(''.'') if re.match(r''[0-9]+.*/.jpg'', f)]

Más flexible, pero como nota, menos eficiente.


Código preliminar

import glob import fnmatch import pathlib import os pattern = ''*.py'' path = ''.''

Solución 1 : use "glob"

# lookup in current dir glob.glob(pattern) In [2]: glob.glob(pattern) Out[2]: [''wsgi.py'', ''manage.py'', ''tasks.py'']

Solución 2 : use "os" + "fnmatch"

Variante 2.1 - Búsqueda en el directorio actual

# lookup in current dir fnmatch.filter(os.listdir(path), pattern) In [3]: fnmatch.filter(os.listdir(path), pattern) Out[3]: [''wsgi.py'', ''manage.py'', ''tasks.py'']

Variante 2.2 - Búsqueda recursiva

# lookup recursive for dirpath, dirnames, filenames in os.walk(path): if not filenames: continue pythonic_files = fnmatch.filter(filenames, pattern) if pythonic_files: for file in pythonic_files: print(''{}/{}''.format(dirpath, file))

Resultado

./wsgi.py ./manage.py ./tasks.py ./temp/temp.py ./apps/diaries/urls.py ./apps/diaries/signals.py ./apps/diaries/actions.py ./apps/diaries/querysets.py ./apps/library/tests/test_forms.py ./apps/library/migrations/0001_initial.py ./apps/polls/views.py ./apps/polls/formsets.py ./apps/polls/reports.py ./apps/polls/admin.py

Solución 3 : use "pathlib"

# lookup in current dir path_ = pathlib.Path(''.'') tuple(path_.glob(pattern)) # lookup recursive tuple(path_.rglob(pattern))

Notas:

  1. Probado en Python 3.4
  2. El módulo "pathlib" se agregó solo en Python 3.4
  3. Python 3.5 agregó una característica para la búsqueda recursiva con glob.glob https://docs.python.org/3.5/library/glob.html#glob.glob . Como mi máquina está instalada con Python 3.4, no lo he probado.

import os dir="/path/to/dir" [x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]

Esto le dará una lista de archivos jpg con su ruta completa. Puede reemplazar x[0]+"/"+f con f solo para nombres de archivos. También puede reemplazar f.endswith(".jpg") con cualquier condición de secuencia que desee.