2014-05-19 2 views
3

Comment utiliser glob pour lire uniquement un ensemble limité de fichiers?Comment utiliser glob pour lire un ensemble limité de fichiers avec des noms numériques?

J'ai des fichiers json nommés numéros de 50 à 20000 (par exemple 50.json, 51.json, 52.json ... 19999.json, 20000.json) dans le même répertoire. Je veux lire seulement les fichiers numérotés de 15000 à 18000.

Pour ce faire j'utilise un glob, comme indiqué ci-dessous, mais il génère une liste vide chaque fois que j'essaie de filtrer les nombres. J'ai essayé de mon mieux de suivre ce lien (https://docs.python.org/2/library/glob.html), mais je ne suis pas sûr de ce que je fais mal.

>>> directory = "/Users/Chris/Dropbox" 
>>> read_files = glob.glob(directory+"/[15000-18000].*") 
>>> print read_files 
[] 

De plus, que se passe-t-il si je veux des fichiers avec un nombre supérieur à 18000?

Répondre

7

Vous utilisez incorrectement la syntaxe glob; la séquence [..] fonctionne par caractère. La glob suivante correspondrait à vos fichiers correctement à la place:

'1[5-8][0-9][0-9][0-9].*' 

Sous les couvertures, glob utilise fnmatch qui se traduit par le motif à une expression régulière. Votre modèle se traduit par:

>>> import fnmatch 
>>> fnmatch.translate('[15000-18000].*') 
'[15000-18000]\\..*\\Z(?ms)' 

qui correspond caractère avant le ., un 0, 1, 5 ou 8. Rien d'autre.

glob les motifs sont assez limités; l'alignement des plages numériques n'est pas facile avec cela; vous devez créer séparé globes pour les gammes, par exemple (glob('1[8-9][0-9][0-9][0-9]') + glob('2[0-9][0-9][0-9][0-9]'), etc.).

Faites votre filtrage à la place:

directory = "/Users/Chris/Dropbox" 

for filename in os.listdir(directory): 
    basename, ext = os.path.splitext(filename) 
    if ext != '.json': 
     continue 
    try: 
     number = int(basename) 
    except ValueError: 
     continue # not numeric 
    if 18000 <= number <= 19000: 
     # process file 
     filename = os.path.join(directory, filename) 
+0

Et si je voulais seulement lire les fichiers après disons 18000. Avez-vous des suggestions ici? – Chris

+1

À quelle hauteur vont les chiffres? 'glob' est vraiment très limité; tous les noms de fichiers sont lus dans le répertoire puis filtrés. Vous pouvez toujours faire votre propre filtrage à la place. –

+0

Eh bien, les fichiers sont ajoutés au fil du temps. Environ 50 fichiers sont générés par jour et je suis sur le fichier 19000. J'ai du mal à implémenter 18000 à 29000 avec ceci: "/ [1-2] [0-9] [0-9] [0-9] [ 0-9].* ", puisque je ne veux pas 10000 à 18000 – Chris

2

Bien qu'il ne compte guère que beau code, vous pouvez mettre en œuvre votre propre filtrage comme suit:

import os, re 
directory = "/Users/Chris/Dropbox" 
all_files = os.listdir(directory) 

read_files = [this_file for this_file in all_files 
       if (int(re.findall('\d+', this_file)[-1]) > 18000)] 

print read_files 

La ligne cruciale ici (devrait) itérer chaque nom de fichier dans le répertoire (for this_file in all_files), extraire une liste de segments de numéro dans ce nom de fichier (re.findall('\d+', this_file)) et l'inclure dans read_files si le dernier de ces segments de nombre, sous la forme d'un entier, est supérieur à 18000.

Je pense que cela va casser sur les fichiers sans entiers dans le nom, alors méfiez-vous de l'utilisateur.


Edit: Je vois la réponse précédente a été modifié afin d'inclure ce qui semble une façon de faire beaucoup mieux pensé.

Questions connexes