recursive from files filename python glob

from - glob python install



Python glob mĂșltiples tipos de archivos (23)

¿Hay alguna forma mejor de usar glob.glob en python para obtener una lista de varios tipos de archivos como .txt, .mdown y .markdown? En este momento tengo algo como esto:

projectFiles1 = glob.glob( os.path.join(projectDir, ''*.txt'') ) projectFiles2 = glob.glob( os.path.join(projectDir, ''*.mdown'') ) projectFiles3 = glob.glob( os.path.join(projectDir, ''*.markdown'') )


Aquí hay una variante de comprensión de lista de una línea de la respuesta de Pat (que también incluye que usted quería englobar en un directorio de proyecto específico):

import os, glob exts = [''*.txt'', ''*.mdown'', ''*.markdown''] files = [f for ext in exts for f in glob.glob(os.path.join(project_dir, ext))]

Usted for ext in exts las extensiones ( for ext in exts ), y luego para cada extensión toma cada archivo que coincida con el patrón glob ( for f in glob.glob(os.path.join(project_dir, ext) ).

Esta solución es corta y sin bucles for innecesarios, comprensiones de listas anidadas o funciones que atestan el código. Solo Zen puro, expresivo y pitónico.

Esta solución le permite tener una lista personalizada de exts que se puede cambiar sin tener que actualizar su código. (¡Esta es siempre una buena práctica!)

La comprensión de la lista es la misma utilizada en la solución de Laurent (que he votado). Pero yo diría que generalmente no es necesario factorizar una sola línea en una función separada, razón por la cual estoy proporcionando esto como una solución alternativa.

Prima:

Si necesita buscar no solo un directorio, sino también todos los subdirectorios, puede pasar recursive=True y usar el símbolo global de multi-directorio ** 1 :

files = [f for ext in exts for f in glob.glob(os.path.join(project_dir, ''**'', ext), recursive=True)]

Esto invocará glob.glob(''<project_dir>/**/*.txt'', recursive=True) y así sucesivamente para cada extensión.

1 Técnicamente, el símbolo ** glob simplemente coincide con uno o más caracteres, incluida la barra diagonal / (a diferencia del singular * símbolo glob). En la práctica, solo necesita recordar que siempre que rodee ** con barras diagonales (separadores de ruta), coincide con cero o más directorios.


Después de venir aquí en busca de ayuda, hice mi propia solución y quería compartirla. Se basa en la respuesta de user2363986, pero creo que es más escalable. Es decir, si tienes 1000 extensiones, el código aún se verá algo elegante.

from glob import glob directoryPath = "C://temp//*." fileExtensions = [ "jpg", "jpeg", "png", "bmp", "gif" ] listOfFiles = [] for extension in fileExtensions: listOfFiles.extend( glob( directoryPath + extension )) for file in listOfFiles: print(file) # Or do other stuff


Encadena los resultados:

import itertools as it, glob def multiple_file_types(*patterns): return it.chain.from_iterable(glob.iglob(pattern) for pattern in patterns)

Entonces:

for filename in multiple_file_types("*.txt", "*.sql", "*.log"): # do stuff


Esta es una solución Python 3.4+ pathlib :

exts = ".pdf", ".doc", ".xls", ".csv", ".ppt" filelist = (str(i) for i in map(pathlib.Path, os.listdir(src)) if i.suffix.lower() in exts and not i.stem.startswith("~"))

También ignora todos los nombres de archivo que comienzan con ~ .


Esto debería funcionar:

import glob extensions = (''*.txt'', ''*.mdown'', ''*.markdown'') for i in extensions: for files in glob.glob(i): print (files)


He lanzado Formic que implementa múltiples incluye de manera similar a FileSet y Globs de Apache Ant.

La búsqueda puede ser implementada:

import formic patterns = ["*.txt", "*.markdown", "*.mdown"] fileset = formic.FileSet(directory=projectDir, include=patterns) for file_name in fileset.qualified_files(): # Do something with file_name

Debido a que se implementa el Ant glob completo, puede incluir diferentes directorios con cada patrón, por lo que puede elegir solo los archivos .txt en un subdirectorio y el .markdown en otro, por ejemplo:

patterns = [ "/unformatted/**/*.txt", "/formatted/**/*.mdown" ]

Espero que esto ayude.


La siguiente función _glob globs para múltiples extensiones de archivo.

import glob import os def _glob(path, *exts): """Glob for multiple file extensions Parameters ---------- path : str A file name without extension, or directory name exts : tuple File extensions to glob for Returns ------- files : list list of files matching extensions in exts in path """ path = os.path.join(path, "*") if os.path.isdir(path) else path + "*" return [f for files in [glob.glob(path + ext) for ext in exts] for f in files] files = _glob(projectDir, ".txt", ".mdown", ".markdown")


No es glob , pero esta es otra forma de usar una lista de comprensión:

extensions = ''txt mdown markdown''.split() projectFiles = [f for f in os.listdir(projectDir) if os.path.splitext(f)[1][1:] in extensions]


Para glob varios tipos de archivos, necesita llamar a la función glob() varias veces en un bucle. Como esta función devuelve una lista, debe concatenar las listas.

Por ejemplo, esta función hace el trabajo:

import glob import os def glob_filetypes(root_dir, *patterns): return [path for pattern in patterns for path in glob.glob(os.path.join(root_dir, pattern))]

Uso simple:

project_dir = "path/to/project/dir" for path in sorted(glob_filetypes(project_dir, ''*.txt'', ''*.mdown'', ''*.markdown'')): print(path)

También puede usar glob.iglob() para tener un iterador:

Devuelve un iterador que produce los mismos valores que glob () sin almacenarlos todos simultáneamente.

def iglob_filetypes(root_dir, *patterns): return (path for pattern in patterns for path in glob.iglob(os.path.join(root_dir, pattern)))


Podría usar filter:

import os import glob projectFiles = filter( lambda x: os.path.splitext(x)[1] in [".txt", ".mdown", ".markdown"] glob.glob(os.path.join(projectDir, "*")) )


Por ejemplo, para *.mp3 y *.flac en varias carpetas, puede hacer:

mask = r''music/*/*.[mf][pl][3a]*'' glob.glob(mask)

La idea se puede extender a más extensiones de archivo, pero debe verificar que las combinaciones no coincidan con ninguna otra extensión de archivo no deseado que pueda tener en esas carpetas. Por lo tanto, ten cuidado con esto.


Puede tratar de hacer una lista manual comparando la extensión existente con las que necesita.

ext_list = [''gif'',''jpg'',''jpeg'',''png'']; file_list = [] for file in glob.glob(''*.*''): if file.rsplit(''.'',1)[1] in ext_list : file_list.append(file)


Tal vez hay una mejor manera, pero ¿qué tal?

>>> import glob >>> types = (''*.pdf'', ''*.cpp'') # the tuple of file types >>> files_grabbed = [] >>> for files in types: ... files_grabbed.extend(glob.glob(files)) ... >>> files_grabbed # the list of pdf and cpp files

Tal vez haya otra forma, así que espere en caso de que alguien encuentre una mejor respuesta.


También podrías usar reduce() manera:

import glob file_types = [''*.txt'', ''*.mdown'', ''*.markdown''] project_files = reduce(lambda list1, list2: list1 + list2, (glob.glob(t) for t in file_types))

esto crea una lista de glob.glob() para cada patrón y los reduce a una sola lista.


Tuve el mismo problema y esto es lo que se me ocurrió

import os, sys, re #without glob src_dir = ''/mnt/mypics/'' src_pics = [] ext = re.compile(''.*/.(|{}|)$''.format(''|''.join([''png'', ''jpeg'', ''jpg'']).encode(''utf-8''))) for root, dirnames, filenames in os.walk(src_dir): for filename in filter(lambda name:ext.search(name),filenames): src_pics.append(os.path.join(root, filename))


Un globo, muchas extensiones ... pero una solución imperfecta (podría coincidir con otros archivos).

filetypes = [''tif'', ''jpg''] filetypes = zip(*[list(ft) for ft in filetypes]) filetypes = ["".join(ch) for ch in filetypes] filetypes = ["[%s]" % ch for ch in filetypes] filetypes = "".join(filetypes) + "*" print(filetypes) # => [tj][ip][fg]* glob.glob("/path/to/*.%s" % filetypes)


Un trazador de líneas, solo por el placer de hacerlo ..

folder = "C://multi_pattern_glob_one_liner" files = [item for sublist in [glob.glob(folder + ext) for ext in ["/*.txt", "/*.bat"]] for item in sublist]

salida:

[''C://multi_pattern_glob_one_liner//dummy_txt.txt'', ''C://multi_pattern_glob_one_liner//dummy_bat.bat'']


con glob no es posible. solo puedes usar:
* coincide con todo
? coincide con cualquier personaje
[seq] coincide con cualquier carácter en seq
[! seq] coincide con cualquier carácter que no esté en seq

use os.listdir y una expresión regular para verificar patrones:

for x in os.listdir(''.''): if re.match(''.*/.txt|.*/.sql'', x): print x


esto funcionó para mí:

import glob images = glob.glob(''*.JPG'' or ''*.jpg'' or ''*.png'')


glob devuelve una lista: ¿por qué no simplemente ejecutarlo varias veces y concatenar los resultados?

from glob import glob ProjectFiles = glob(''*.txt'') + glob(''*.mdown'') + glob(''*markdown'')


files = glob.glob(''*.txt'') files.extend(glob.glob(''*.dat''))


from glob import glob files = glob(''*.gif'') files.extend(glob(''*.png'')) files.extend(glob(''*.jpg'')) print(files)

Si necesita especificar una ruta, repita los patrones de coincidencia y mantenga la combinación dentro del ciclo para simplificar:

from os.path import join from glob import glob files = [] for ext in (''*.gif'', ''*.png'', ''*.jpg''): files.extend(glob(join("path/to/dir", ext))) print(files)