Tengo un directorio con un montón de archivos dentro: eee2314
, asd3442
... y eph
.
Quiero excluir todos los archivos que comienzan eph
con la glob
función.
¿Cómo puedo hacerlo?
Las reglas de patrón para glob no son expresiones regulares. En cambio, siguen las reglas de expansión de ruta estándar de Unix. Hay sólo unos pocos caracteres especiales: se admiten dos comodines diferentes y rangos de caracteres [de glob ].
De modo que puede excluir algunos archivos con patrones.
Por ejemplo, para excluir archivos de manifiesto (archivos que comienzan con _
) con glob, puede usar:
files = glob.glob('files_path/[!_]*')
eph
pero pueden comenzar con cualquier otra cosa.[!e][!p][!h]
filtrará los archivos que comiencen con,eee
por ejemplo.Puede deducir conjuntos:
set(glob("*")) - set(glob("eph*"))
fuente
set(glob("*")) - set(glob("eph*"))
(y observe * al final de "eph *")list(set(glob("*")) - set(glob("eph")))
No puede excluir patrones con la
glob
función, los globs solo permiten patrones de inclusión . La sintaxis globbing es muy limitada (incluso una[!..]
clase de carácter debe coincidir con un carácter, por lo que es un patrón de inclusión para cada carácter que no está en la clase).Tendrá que hacer su propio filtrado; una lista de comprensión suele funcionar bien aquí:
files = [fn for fn in glob('somepath/*.txt') if not os.path.basename(fn).startswith('eph')]
fuente
iglob
aquí para evitar almacenar la lista completa en la memoriaiglob
produce listas de todos modos ; todo lo que hace es evaluar perezosamente el filtro. No ayudará a reducir la huella de memoria.os.listdir()
resultado se mantiene en la memoria mientras itera. Perosomepath/*.txt
tiene que leer todos los nombres de archivo en un directorio en la memoria, luego reducir esa lista a solo aquellos que coincidan.glob.glob(x) = list(glob.iglob(x))
. No es una gran sobrecarga, pero es bueno saberlo.Tarde en el juego, pero también puedes aplicar una pitón
filter
al resultado deglob
:files = glob.iglob('your_path_here') files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
o reemplazando el lambda con una búsqueda de expresiones regulares apropiada, etc.
EDITAR: Me acabo de dar cuenta de que si está utilizando rutas completas
startswith
, no funcionará, por lo que necesitaría una expresión regularIn [10]: a Out[10]: ['/some/path/foo', 'some/path/bar', 'some/path/eph_thing'] In [11]: filter(lambda x: not re.search('/eph', x), a) Out[11]: ['/some/path/foo', 'some/path/bar']
fuente
¿Qué tal si se salta el archivo en particular mientras se itera sobre todos los archivos de la carpeta? El siguiente código omitiría todos los archivos de Excel que comienzan con 'eph'
import glob import re for file in glob.glob('*.xlsx'): if re.match('eph.*\.xlsx',file): continue else: #do your stuff here print(file)
De esta manera, puede usar patrones de expresiones regulares más complejos para incluir / excluir un conjunto particular de archivos en una carpeta.
fuente
Comparar con
glob
, recomiendopathlib
, filtrar un patrón es muy simple.from pathlib import Path p = Path(YOUR_PATH) filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
y si desea filtrar un patrón más complejo, puede definir una función para hacer eso, como:
def not_in_pattern(x): return (not x.name.startswith("eph")) and not x.name.startswith("epi") filtered = [x for x in p.glob("**/*") if not_in_pattern(x)]
use ese código, puede filtrar todos los archivos que comienzan con
eph
o comienzan conepi
.fuente
De manera más general, para excluir archivos que no cumplen con algunas expresiones regulares de shell, puede usar el módulo
fnmatch
:import fnmatch file_list = glob('somepath') for ind, ii in enumerate(file_list): if not fnmatch.fnmatch(ii, 'bash_regexp_with_exclude'): file_list.pop(ind)
Lo anterior generará primero una lista a partir de una ruta determinada y luego mostrará los archivos que no satisfagan la expresión regular con la restricción deseada.
fuente
Como se menciona en la respuesta aceptada, no puede excluir patrones con glob, por lo que el siguiente es un método para filtrar su resultado glob.
La respuesta aceptada es probablemente la mejor forma pitónica de hacer las cosas, pero si crees que las listas de comprensión se ven un poco feas y quieres que tu código sea lo más numpythonic de todos modos (como hice yo), entonces puedes hacer esto (pero ten en cuenta que probablemente sea menos eficiente que el método de comprensión de listas):
import glob data_files = glob.glob("path_to_files/*.fits") light_files = np.setdiff1d( data_files, glob.glob("*BIAS*")) light_files = np.setdiff1d(light_files, glob.glob("*FLAT*"))
(En mi caso, tenía algunos marcos de imagen, marcos de sesgo y marcos planos en un directorio y solo quería los marcos de imagen)
fuente
Si la posición del carácter no es importante, es decir, por ejemplo, para excluir archivos de manifiesto (donde sea que se encuentre
_
) conglob
yre
- operaciones de expresión regular , puede usar:import glob import re for file in glob.glob('*.txt'): if re.match(r'.*\_.*', file): continue else: print(file)
O de una manera más elegante -
list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)] for mach in filtered: print(mach)
fuente
Puede utilizar el siguiente método:
# Get all the files allFiles = glob.glob("*") # Files starting with eph ephFiles = glob.glob("eph*") # Files which doesnt start with eph noephFiles = [] for file in allFiles: if file not in ephFiles: noephFiles.append(file) # noepchFiles has all the file which doesnt start with eph. Thank you.
fuente