glob - Corrispondenza su un modello di nome di file
Scopo: Usa le regole della shell UNIX per trovare nomi di file che corrispondono ad un modello.
Sebbene l'API di glob sia piccola, il modulo è dotato di molta potenza. E' utile in qualsiasi situazione nella quale un programma debba cercare nel file system una lista di file i cui nomi corrispondono ad un modello. Per creare una lista di nomi di file che abbiano tutti una certa estensione, prefisso od altra stringa comune all'interno, si utilizzi glob piuttosto che scrivere del proprio codice per esaminare il contenuto di una directory.
Le regole del modello per glob non solo le stesse delle espressioni regolari utilizzate dal modulo re
. Viceversa esse seguono le regole standard UNIX per l'espansione del percorso. Ci sono solo alcuni caratteri speciali utilizzati per implementare due diversi intervalli di caratteri e caratteri jolly. Le regole del modello sono applicate a segmenti del nome di file (che si interrompono al separatore di percorso, /). I percorsi nel modello possono essere relativi od assoluti. I nomi di variabile della shell ed il carattere tilde (~) non sono espansi.
Dati di Esempio
Gli esempi di questa sezione assumono che i seguenti file di prova siano presenti nella directory di lavoro corrente. Questa struttura di esempio può essere creata con il seguente script:
# glob_maketestdata.py
import os
import os.path
import glob
if not os.path.exists('dir'):
os.mkdir('dir')
if not os.path.exists('dir/subdir'):
os.mkdir('dir/subdir')
os.chdir('dir')
fh = open('file.txt', 'w')
fh.close()
fh = open('file1.txt', 'w')
fh.close()
fh = open('file2.txt', 'w')
fh.close()
fh = open('filea.txt', 'w')
fh.close()
fh = open('fileb.txt', 'w')
fh.close()
fh = open('file?.txt', 'w')
fh.close()
fh = open('file*.txt', 'w')
fh.close()
fh = open('file[.txt', 'w')
fh.close()
fh = open('subdir/subfile.txt', 'w')
fh.close()
print("\n".join(glob.glob('dir')))
print("\n".join(sorted(glob.glob('dir/*'))))
print("\n".join(glob.glob('dir/subdir/*')))
$ python3 glob_maketestdata.py dir dir/file*.txt dir/file.txt dir/file1.txt dir/file2.txt dir/file?.txt dir/file[.txt dir/filea.txt dir/fileb.txt dir/subdir dir/subdir/subfile.txt
Caratteri Jolly
Un asterisco (*
) corrisponde a zero o più caratteri in un segmento di un nome. Ad esempio dir/*
.
# glob_asterisk.py
import glob
for name in sorted(glob.glob('dir/*')):
print(name)
Il modello trova corrispondenza per ogni nome di percorso (file o directory) nella directory dir
, senza effettuare una ricorsione nelle sottodirectory. I dati restituiti da glob()
non sono ordinati, quindi gli esempi di seguito applicano un ordinamento per facilitare l'esame dei risultati.
$ python3 glob_asterisk.py dir/file*.txt dir/file.txt dir/file1.txt dir/file2.txt dir/file?.txt dir/file[.txt dir/filea.txt dir/fileb.txt dir/subdir
Per elencare i file in una sottodirectory, essa deve essere inclusa nel modello.
# glob_subdir.py
import glob
print('Nominata esplicitamente:')
for name in sorted(glob.glob('dir/subdir/*')):
print('\t', name)
print('nominata con caratteri jolly:')
for name in sorted(glob.glob('dir/*/*')):
print('\t', name)
Il primo caso nell'esempio qui sopra elenca la sottodirectory esplicitamente, il secondo si affida ai caratteri jolly per trovare la sottodirectory.
$ python3 glob_subdir.py Nominata esplicitamente: dir/subdir/subfile.txt nominata con caratteri jolly: dir/subdir/subfile.txt
I risultati, in questo caso, sono identici. Se ci fosse stata un'altra sottodirectory, i caratteri jolly avrebbero consentito una corrispondenza con entrambe le sottodirectory e sarebbero stati elencati i file presenti in entrambe.
Carattere Jolly per Singolo Carattere
Un punto interrogativo (?
) è un altro carattere jolly. Trova corrispondenza con qualsiasi carattere singolo in quella posizione nel nome.
# glob_question.py
import glob
for name in sorted(glob.glob('dir/file?.txt')):
print(name)
Nell'esempio qui sopra si trova corrispondenza con tutti i nomi di file che iniziano con file
, hanno un ulteriore carattere di qualunque tipo, e finiscono con .txt
.
$ python3 glob_question.py dir/file*.txt dir/file1.txt dir/file2.txt dir/file?.txt dir/file[.txt dir/filea.txt dir/fileb.txt
Gruppi di Caratteri
Si utilizza un gruppo di caratteri ([a-z]
) al posto del punto interrogativo per cercare corrispondenza con uno di parecchi caratteri. Questo esempio cerca tutti i file con una cifra nel nome prima dell'estensione.
# glob_charrange.py
import glob
for name in sorted(glob.glob('dir/*[0-9].*')):
print(name)
Il gruppo di caratteri [0-9]
trova corrispondenza con qualsiasi cifra. Il gruppo viene ordinato in base al codice del carattere di ciascuna lettera/cifra, mentre il trattino indica un gruppo sequenziale ininterrotto di caratteri. Lo stesso gruppo di valori avrebbe potuto essere scritto come [0123456789]
.
$ python3 glob_charrange.py dir/file1.txt dir/file2.txt
Considerare Meta-caratteri Come Parte di una Ricerca
Talvolta è necessario cercare dei file con nomi che contengono gli speciali meta-caratteri che glob utilizza per i suoi modelli. La funzione escape()
costruisce un modello appropriato con i caratteri speciali trattati in modo da non venire espansi od interpretati come speciali da glob.
# glob_escape.py
import glob
specials = '?*['
for char in specials:
pattern = 'dir/*' + glob.escape(char) + '.txt'
print('Ricerca di: {!r}'.format(pattern))
for name in sorted(glob.glob(pattern)):
print(name)
print()
Ogni carattere speciale non viene considerato come tale costruendo un gruppo di caratteri che contiene un singolo elemento.
$ python3 glob_escape.py Ricerca di: 'dir/*[?].txt' dir/file?.txt Ricerca di: 'dir/*[*].txt' dir/file*.txt Ricerca di: 'dir/*[[].txt' dir/file[.txt
Vedere anche:
- glob
- La documentazione della libreria standard per questo modulo.
- Pattern Matching Notation
- Spiegazione (in inglese) del globbing secondo le specifiche del linguaggio dei comandi della Shell da parte di Open Group
- fnmatch
- Implementazione della corrispondenza del nome di file
- Note di portabilità per glob