Scopo | Usa le regole della shell Unix per trovare nomi di file che corrispondono ad un modello |
Versione Python | 1.4 |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per il modulo glob
Sebbene l' API di glob sia molto semplice, il modulo racchiude molta potenza. E' utile in qualsiasi situazione nella quale un programma debba cercare un elenco di file nel filesystem i cui nomi corrispondano ad un modello. Se occorre un elenco di file che abbiano una certa estensione, prefisso od una stringa comune all'interno, si usi glob invece che scrivere codice che analizzi il contentuto della directory.
Le regole di corrispondenza per glob non sono le espressioni regolari, bensì seguono le regole standard di espansione del percorso di Unix. Ci sono solo pochi caratteri speciali: due diversi caratteri jolly, e vengono supportati gli intervalli di caratteri. Le regole di corrispondenza sono applicate a segmenti del nome del file (terminando al separatore di percorso "/" ad esempio nei sistemi derivati da Unix). I percorsi nel modello possono essere relativi od assoluti. I nomi delle variabili della shell ed il simbolo della home utente - la tilde (~) - non vengono espansi.
Si utilizza lo script python di seguito per creare i dati con i quali eseguire gli esempi
import os
if not os.path.exists('dir'): os.mkdir('dir')
if not os.path.exists('dir/subdir'): os.mkdir('dir/subdir')
os.chdir('dir')
fh = file ('file.txt', 'w')
fh.close();
fh = file ('file1.txt', 'w')
fh.close();
fh = file ('file2.txt', 'w')
fh.close();
fh = file ('filea.txt', 'w')
fh.close();
fh = file ('fileb.txt', 'w')
fh.close();
fh = file ('subdir/subfile.txt', 'w')
fh.close();
$ python glob_maketestdata.py dir dir/file.txt dir/file1.txt dir/file2.txt dir/filea.txt dir/fileb.txt dir/subdir dir/subdir/subfile.txt
Un asterisco (*) corrisponde a zero o più caratteri in un segmento di un nome. As esempio
dir/*
.
import glob
for name in glob.glob('dir/*'):
print name
Il modello corrisponde ad ogni percorso (nome di file o directory) nella directory dir, senza ricorsione in sottodirectory.
$ python glob_asterisk.py dir/file.txt dir/file1.txt dir/file2.txt dir/filea.txt dir/fileb.txt dir/subdir
Per elencare i file in una sottodirectory, si deve includere nel modello la sottodirectory
import glob
print 'Sottodirectory nominata esplicitamente:'
for name in glob.glob('dir/subdir/*'):
print '\t', name
print 'Sottodirectory nominata con caratteri jolly:'
for name in glob.glob('dir/*/*'):
print '\t', name
Nel primo caso dell'esempio di cui sopra il nome della sottodirectory viene scritto esplicitamente mentre nel secondo caso ci si affida ai caratteri jolly per trovare la directory.
Sottodirectory nominata esplicitamente: dir/subdir/subfile.txt Sottodirectory nominata con caratteri jolly: dir/subdir/subfile.txt
I risultati, in questo caso, sono gli stessi: se ci fosse stata un'altra sottodirectory, i caratteri jolly avrebbero trovato corrispondenza in entrambe le sottodirectory ed avrebbero incluso i nomi dei file di entrambe.
L'altro carattere jolly supportato è il punto interrogativo (?). Corrisponde ad un qualsiasi singolo carattere in quella posizione nel nome. Ad sempio:
import glob
for name in glob.glob('dir/file?.txt'):
print name
Corrisponde a tutti i nomi di file che iniziano per "file", hanno un ulteriore carattere di qualsiasi tipo, quindi terminano con ".txt".
$ python glob_question.py dir/file1.txt dir/file2.txt dir/filea.txt dir/fileb.txt
In modalità predefinita, l'handle del file viene creato con modalità 'w+b', in modo che si comporti consistentemente su tutte le piattaforme ed un programma possa scrivere o leggere da esso.
Quando serve trovare una corrispondenza con un carattere specifico si usa un intervallo di caratteri invece che il punto interrogativo. Ad esempio, per trovare tutti i file che hanno una cifra nel nome prima dell'estensione:
import glob
for name in glob.glob('dir/*[0-9].*'):
print name
L'intervallo di caratteri [0-9] trova corrispondenza con ogni singola cifra. L'intervallo viene ordinato in base al codice del carattere di ogni lettera/cifra al suo interno, ed il trattino indica un intervallo continuo di caratteri sequenziali. Lo stesso valore dell'intervallo potrebbe essere scritto [0123456789] in questo caso.
$ python glob_charrange.py dir/file1.txt dir/file2.txt
Vedere anche:
Vedere anche: