Successivo: , Su: Record   [Contenuti][Indice]


4.1.1 Come awk standard divide i record.

I record sono separati da un carattere chiamato separatore di record. Per default, il separatore di record è il carattere di ritorno a capo. Questo è il motivo per cui i record sono, per default, righe singole. Per usare un diverso carattere come separatore di record basta assegnare quel carattere alla variabile predefinita RS.

Come per ogni altra variabile, il valore di RS può essere cambiato nel programma awk con l’operatore di assegnamento, ‘=’ (vedi la sezione Espressioni di assegnamento). Il nuovo separatore di record dovrebbe essere racchiuso tra doppi apici, per indicare una costante di stringa. Spesso il momento giusto per far questo è all’inizio dell’esecuzione, prima che sia elaborato qualsiasi input, in modo che il primo record sia letto col separatore appropriato. Per far ciò, si usa il criterio speciale BEGIN (vedi la sezione I criteri di ricerca speciali BEGIN ed END). Per esempio:

awk 'BEGIN { RS = "u" }
     { print $0 }' mail-list

cambia il valore di RS in ‘u’, prima di leggere qualsiasi input. Il nuovo valore è una stringa il cui primo carattere è la lettera “u”; come risultato, i record sono separati dalla lettera “u”. Poi viene letto il file in input, e la seconda regola nel programma awk (l’azione eseguita se non si specifica un criterio) stampa ogni record. Poiché ogni istruzione print aggiunge un ritorno a capo alla fine del suo output, questo programma awk copia l’input con ogni ‘u’ trasformato in un ritorno a capo. Qui vediamo il risultato dell’esecuzione del programma sul file mail-list:

$ awk 'BEGIN { RS = "u" }
>      { print $0 }' mail-list
-| Amelia       555-5553     amelia.zodiac
-| sq
-| e@gmail.com    F
-| Anthony      555-3412     anthony.assert
-| ro@hotmail.com   A
-| Becky        555-7685     becky.algebrar
-| m@gmail.com      A
-| Bill         555-1675     bill.drowning@hotmail.com       A
-| Broderick    555-0542     broderick.aliq
-| otiens@yahoo.com R
-| Camilla      555-2912     camilla.inf
-| sar
-| m@skynet.be     R
-| Fabi
-| s       555-1234     fabi
-| s.
-| ndevicesim
-| s@
-| cb.ed
-|     F
-| J
-| lie        555-6699     j
-| lie.perscr
-| tabor@skeeve.com   F
-| Martin       555-6480     martin.codicib
-| s@hotmail.com    A
-| Sam
-| el       555-3430     sam
-| el.lanceolis@sh
-| .ed
-|         A
-| Jean-Pa
-| l    555-2127     jeanpa
-| l.campanor
-| m@ny
-| .ed
-|      R
-|

Si noti che la voce relativa al nome ‘Bill’ non è divisa. Nel file-dati originale (vedi la sezione File-dati per gli esempi), la riga appare in questo modo:

Bill         555-1675     bill.drowning@hotmail.com       A

Essa non contiene nessuna ‘u’, per cui non c’è alcun motivo di dividere il record, diversamente dalle altre, che hanno una o più ricorrenze della ‘u’. Infatti, questo record è trattato come parte del record precedente; il ritorno a capo che li separa nell’output è l’originale ritorno a capo nel file-dati, non quella aggiunta da awk quando ha stampato il record!

Un altro modo per cambiare il separatore di record è sulla riga di comando, usando la funzionalità dell’assegnamento di variabile (vedi la sezione Altri argomenti della riga di comando):

awk '{ print $0 }' RS="u" mail-list

Questo imposta RS a ‘u’ prima di elaborare mail-list.

Usando un carattere alfabetico come ‘u’ come separatore di record è molto probabile che si ottengano risultati strani. Usando un carattere insolito come ‘/’ è più probabile che si ottenga un comportamento corretto nella maggioranza dei casi, ma non c’è nessuna garanzia. La morale è: conosci i tuoi dati!

gawk consente di usare per RS un’espressione regolare normale (descritta più avanti; vedi la sezione Divisione dei record con gawk). Tuttavia, se l’espressione regolare è costituita da un singolo metacarattere, come p.es. ‘.’ che assegni il valore di RS, il metacarattere in questione non viene trattato come tale, ma viene usato letteralmente. Ciò viene fatto per compatibilità all’indietro sia con il comando Unix awk che con lo standard POSIX.

Quando si usano caratteri normali come separatore di record, c’è un caso insolito che capita quando gawk è reso completamente conforme a POSIX (vedi la sezione Opzioni sulla riga di comando). In quel caso, la seguente (estrema) pipeline stampa un sorprendente ‘1’:

$ echo | gawk --posix 'BEGIN { RS = "a" } ; { print NF }'
-| 1

C’è un solo campo, consistente in un ritorno a capo. Il valore della variabile predefinita NF è il numero di campi nel record corrente. (Normalmente gawk tratta il ritorno a capo come uno spazio vuoto, stampando ‘0’ come risultato. Anche molte altre versioni di awk agiscono in questo modo.)

Il raggiungimento della fine di un file in input fa terminare il record di input corrente, anche se l’ultimo carattere nel file non è il carattere in RS. (a.b.)

La stringa nulla "" (una stringa che non contiene alcun carattere) ha un significato particolare come valore di RS. Significa che i record sono separati soltanto da una o più righe vuote. Vedi la sezione Record su righe multiple per maggiori dettagli.

Se si cambia il valore di RS nel mezzo di un’esecuzione di awk, il nuovo valore è usato per delimitare i record successivi, ma non riguarda il record in corso di elaborazione e neppure quelli già elaborati.

Dopo che è stata determinata la fine di un record, gawk imposta la variabile RT al testo nell’input che corrisponde a RS.


Successivo: , Su: Record   [Contenuti][Indice]