web-dev-qa-db-fra.com

modèle d'exclusion glob

J'ai un répertoire avec un tas de fichiers à l'intérieur: eee2314, asd3442 ... et eph.

Je veux exclure tous les fichiers qui commencent par eph avec la fonction glob.

Comment puis-je le faire?

64

Les règles de modèle pour glob ne sont pas des expressions régulières. Au lieu de cela, ils suivent les règles standard de développement du chemin Unix. Il n'y a que quelques caractères spéciaux: deux caractères génériques différents et les plages de caractères sont prises en charge [from glob ].

Ainsi, vous pouvez exclure certains fichiers avec des modèles.
Par exemple, pour exclure des fichiers manifestes (fichiers commençant par _) avec glob, vous pouvez utiliser:

files = glob.glob('files_path/[!_]*')
91
zety

Vous ne pouvez pas exclure les patterns avec la fonction glob, les globs n'autorisent que les patterns . syntaxe Globbing est très limité (même un [!..] la classe de caractères doit correspondre à un caractère; il s’agit donc d’un motif d’inclusion pour chaque personnage ne faisant pas partie de la classe).

Vous devrez faire votre propre filtrage; une compréhension de liste fonctionne généralement bien ici:

files = [fn for fn in glob('somepath/*.txt') 
         if not os.path.basename(fn).startswith('eph')]
41
Martijn Pieters

Vous pouvez déduire des ensembles:

set(glob("*")) - set(glob("eph*"))
34
neutrinus

Tard dans le jeu mais vous pouvez aussi simplement appliquer un python filter au résultat d'un glob:

files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)

ou remplacer le lambda par une recherche de regex appropriée, etc ...

EDIT: Je viens de me rendre compte que si vous utilisez des chemins complets, le startswith ne fonctionnera pas, vous aurez donc besoin d'une regex

In [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']
4
K Raphael

Plus généralement, pour exclure les fichiers non conformes à certaines expressions rationnelles de Shell, vous pouvez utiliser le module 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)

Ce qui précède va d'abord générer une liste à partir d'un chemin donné, puis faire apparaître les fichiers qui ne satisferont pas l'expression régulière avec la contrainte souhaitée.

2
Lord Henry Wotton

Que diriez-vous de sauter le fichier en particulier tout en parcourant tous les fichiers du dossier! Le code ci-dessous ignorerait tous les fichiers Excel commençant par '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 cette façon, vous pouvez utiliser des motifs de regex plus complexes pour inclure/exclure un ensemble particulier de fichiers dans un dossier.

2
Azhar Ansari

Comparez avec glob, je recommande pathlib, filtrer un motif est très simple.

from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob('**/*') if not x.name.startswith('eph'))]

et si vous voulez filtrer des motifs plus complexes, vous pouvez définir une fonction pour le faire, comme ceci:

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)]

si vous utilisez ce code, vous pouvez filtrer tous les fichiers commençant par eph ou par epi.

2
Scott Ming

Comme mentionné dans la réponse acceptée, vous ne pouvez pas exclure de modèles avec glob, la méthode suivante permet de filtrer le résultat de votre glob.

La réponse acceptée est probablement la meilleure façon de faire les choses en Pythonic, mais si vous pensez que les compréhensions de liste ont un aspect un peu laid et que vous voulez quand même rendre votre code numpythonique maximal (comme je l’ai fait), vous pouvez le faire (mais notez que cela est probablement moins efficace méthode de compréhension par liste):

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*"))

(Dans mon cas, j'avais des cadres d'image, des cadres en biais et des cadres plats dans un seul répertoire et je voulais juste les cadres d'image)

1
Ryan Farber

Vous pouvez utiliser la méthode ci-dessous:

# 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.  
0
KK2491