Obtener una lista filtrada de archivos en un directorio


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 bucle for para iterar a través de los resultados de un os.listdir() y anexar todos los archivos coincidentes a una nueva lista.

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

Author: Bart, 2010-02-09

10 answers

 265
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-08 23:05:18

glob.glob() es definitivamente la manera de hacerlo (según Ignacio). Sin embargo, si necesitas una comparación más complicada, puedes hacerlo con una comprensión de lista 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 se nota, menos eficiente.

 97
Author: Ben Hoyt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-09 00:27:32

Manténgalo 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.

Leo la cuarta línea como: Para cada fn en os.listdir para mi ruta, dame solo las que coincidan con cualquiera de mis extensiones incluidas.

Puede ser difícil para los programadores principiantes de python acostumbrarse realmente a usar comprensiones de listas para filtrar, y puede tener cierta sobrecarga de memoria para conjuntos de datos muy grandes, pero para listar un directorio y otra cadena simple las tareas de filtrado, las comprensiones de listas conducen a un código documentable más limpio.

Lo único de este diseño es que no te protege contra cometer el error de pasar una cadena en lugar de una lista. Por ejemplo, si accidentalmente convierte una cadena en una lista y termina comprobando todos los caracteres de una cadena, podría terminar obteniendo una gran cantidad de falsos positivos.

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

 29
Author: ramsey0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-09 21:12:47

Otra opción:

>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']

Https://docs.python.org/3/library/fnmatch.html

 27
Author: Risadinha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-05 00:12:56

Use so.camina para listar recursivamente tus 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)
 8
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-26 16:41:07

Código preliminar

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path = '.'

Solución 1 - utilizar"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 . Desde que mi máquina está instalada con Python 3.4, no he probado eso.
 5
Author: Seti Volkylany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-21 12:49:23

También podría gustarle un enfoque de más alto nivel (he implementado y empaquetado como findtools):

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
 2
Author: Yauhen Yakimovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-29 22:13:17
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 por f solo para nombres de archivo. También puede reemplazar f.endswith(".jpg") con cualquier condición de cadena que desee.

 1
Author: EvgenijM86,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-19 13:47:42

Nombres de archivo con extensiones " jpg " y "png"en" path / to / images":

import os
accepted_extensions = ["jpg", "png"]
filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]
 1
Author: gypsy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-22 18:38:33

Puede usar subproceso.check_ouput () as

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.

 0
Author: David A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 13:08:40