Successivo: Funzione rewind, Su: Gestione File Dati [Contenuti][Indice]
Ognuna delle regole BEGIN ed END viene eseguita esattamente
solo una volta, rispettivamente all’inizio e alla fine del programma
awk (vedi la sezione I criteri di ricerca speciali BEGIN ed END).
Una volta noi (gli autori di gawk) siamo venuti in contatto
con un utente che
erroneamemnte pensava che le regole BEGIN venissero eseguite all’inizio
di ogni file-dati e le regole END alla fine di ogni file-dati.
Quando lo abbiamo informato che
non era così, ci ha chiesto di aggiungere un nuovo criterio di ricerca speciale
a gawk, chiamato BEGIN_FILE e END_FILE, che avesse il
comportamento desiderato. Ci ha fornito anche il codice per far questo.
Non è stato necessario aggiungere a gawk questi criteri di ricerca
speciali; il lavoro si può fare tranquillamente usando awk, come
illustrato nel seguente programma di libreria. È strutturato in modo da
chiamare due funzioni fornite dall’utente, a_inizio_file() e
a_fine_file(), all’inizio e alla fine di ogni file-dati. Oltre a risolvere
il problema in sole nove(!) righe di codice,
questa soluzione è portabile; il
programma funziona con qualsiasi implementazione di awk:
# transfile.awk
#
# Dare all'utente un aggancio per il passaggio
# da un file in input a quello successivo
#
# L'utente deve fornire le funzioni a_inizio_file() ed a_fine_file()
# ciascuna delle quali è invocata
# quando il file, rispettivamente,
# inizia e finisce.
FILENAME != _nome_file_vecchio {
if (_nome_file_vecchio != "")
a_fine_file(_nome_file_vecchio)
_nome_file_vecchio = FILENAME
a_inizio_file(FILENAME)
}
END { a_fine_file(FILENAME) }
Questo file [transfile.awk] dev’essere caricato prima del programma “principale” dell’utente, in modo che la regola ivi contenuta venga eseguita per prima.
Questa regola dipende dalla variabile di awk FILENAME, che
cambia automaticamente per ogni nuovo file-dati. Il nome-file corrente viene
salvato in una variabile privata, _nome_file_vecchio. Se FILENAME non è
uguale a _nome_file_vecchio, inizia l’elaborazioone di un nuovo file-dati ed
è necessario chiamare a_fine_file() per il vecchio file. Poiché
a_fine_file() dovrebbe essere chiamato solo se un file è stato elaborato, il
programma esegue prima un controllo per assicurarsi che _nome_file_vecchio non
sia la stringa nulla. Il programma assegna poi il valore corrente di
nome-file a _nome_file_vecchio e chiama a_inizio_file() per il file.
Poiché, come tutte le variabili di awk, _nome_file_vecchio è
inizializzato alla stringa nulla, questa regola viene eseguita correttamente
anche per il primo file-dati.
Il programma contiene anche una regola END per completare l’elaborazione
per l’ultimo file. Poiché questa regola END viene prima di qualsiasi
regola END contenuta nel programma “principale”,
a_fine_file() viene
chiamata per prima. Ancora una volta, l’utilità di poter avere più regole
BEGIN ed END dovrebbe risultare chiara.
Se lo stesso file-dati compare due volte di fila sulla riga di comando,
a_fine_file() e a_inizio_file() non vengono eseguite alla fine del primo
passaggio e all’inizio del secondo passaggio.
La versione seguente risolve il problema:
# ftrans.awk --- gestisce il passaggio da un file dati al successivo
#
# L'utente deve fornire le funzioni a_inizio_file() ed a_fine_file()
FNR == 1 {
if (_filename_ != "")
a_fine_file(_filename_)
_filename_ = FILENAME
a_inizio_file(FILENAME)
}
END { a_fine_file(_filename_) }
Contare cose mostra come utilizzare questa funzione di libreria e come ciò semplifichi la scrittura del programma principale.
|
Allora perché
gawk ha BEGINFILE e ENDFILE?
Ci si chiederà, probabilmente: perché, se le funzioni Buona domanda. Normalmente, se |
Successivo: Funzione rewind, Su: Gestione File Dati [Contenuti][Indice]