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]
Otra opción:
>>> import os, fnmatch
>>> fnmatch.filter(os.listdir(''.''), ''*.py'')
[''manage.py'']
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:
- Probado en Python 3.4
- El módulo "pathlib" se agregó solo en Python 3.4
- 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.