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]