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