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


4.1.2 Divisione dei record con gawk

Quando si usa gawk, il valore di RS non è limitato a una stringa costituita da un solo carattere, ma può essere qualsiasi espressione regolare (vedi Espressioni regolari). (e.c.) In generale, ogni record termina alla stringa più vicina che corrisponde all’espressione regolare; il record successivo inizia alla fine della stringa che corrisponde. Questa regola generale è in realtà applicata anche nel caso normale, in cui RS contiene solo un ritorno a capo: un record termina all’inizio della prossima stringa che corrisponde (il prossimo ritorno a capo nell’input), e il record seguente inizia subito dopo la fine di questa stringa (al primo carattere della riga seguente). Il ritorno a capo, poiché corrisponde a RS, non appartiene a nessuno dei due record.

Quando RS è un singolo carattere, RT contiene lo stesso singolo carattere. Peraltro, quando RS è un’espressione regolare, RT contiene l’effettivo testo in input corrispondente all’espressione regolare.

Se il file in input termina senza che vi sia un testo che corrisponda a RS, gawk imposta RT alla stringa nulla.

Il seguente esempio illustra entrambe queste caratteristiche. In quest’esempio RS è impostato a un’espressione regolare che cerca sia un ritorno a capo che una serie di una o più lettere maiuscole con uno spazio vuoto opzionale iniziale e/o finale:

$ echo record 1 AAAA record 2 BBBB record 3 |
> gawk 'BEGIN { RS = "\n|( *[[:upper:]]+ *)" }
>             { print "Record =", $0,"e RT = [" RT "]" }'
-| Record = record 1 e RT = [ AAAA ]
-| Record = record 2 e RT = [ BBBB ]
-| Record = record 3 e RT = [
-| ]

Le parentesi quadre racchiudono il contenuto di RT, rendendo visibile lo spazio vuoto iniziale e quello finale. L’ultimo valore di RT è un ritorno a capo. Vedi Programma sed semplice per un esempio più utile su RS come espressione regolare e su RT.

Se si imposta RS a un’espressione regolare che consente del testo finale opzionale, come ‘RS = "abc(XYZ)?"’ è possibile, per via di limitazioni dell’implementazione, che gawk possa trovare la parte iniziale dell’espressione regolare, ma non la parte finale, in modo particolare se il testo di input che potrebbe avere una corrispondenza con la parte finale è piuttosto lungo. gawk cerca di evitare questo problema, ma al momento non ci sono garanzie che questo funzioni sempre.

NOTA: Si ricordi che in awk, i metacaratteri di ancoraggio ‘^’ e ‘$’ trovano l’inizio e la fine di una stringa, e non l’inizio e la fine di una riga. Come risultato, qualcosa come ‘RS = "^[[:upper:]]"’ può solo corrispondere all’inizio di un file. Questo perché gawk vede il file in input come un’unica lunga stringa in cui possono essere presenti dei caratteri di ritorno a capo. È meglio perciò evitare metacaratteri di ancoraggio nel valore di RS.

L’uso di RS come espressione regolare e la variabile RT sono estensioni gawk; non sono disponibili in modalità compatibile (vedi Opzioni). In modalità compatibile, solo il primo carattere del valore di RS determina la fine del record.

RS = "\0" non è portabile

Ci sono casi in cui capita di dover trattare un intero file-dati come un record unico. L’unico modo di far questo è quello di dare a RS un valore che non ricorre nel file in input. Ciò è difficile da fare in modo generale, così che un programma possa funzionare con file in input arbitrari.

Si potrebbe pensare che per i file di testo il carattere NUL, che consiste di un carattere con tutti i bit uguali a zero, sia un buon valore da usare per RS in questo caso:

BEGIN { RS = "\0" }  # l'intero file diventa un record?

gawk di fatto lo accetta, e usa il carattere NUL come separatore di record. Questo funziona per certi file speciali, come /proc/environ su sistemi GNU/Linux, dove il carattere NUL è di fatto un separatore di record.. Comunque, quest’uso non è portabile sulla maggior parte delle implementazioni di awk.

Quasi tutte le altre implementazioni di awk 19 memorizzano internamente le stringhe come stringhe in stile C. Le stringhe in stile C usano il carattere NUL come terminatore di stringa. In effetti, questo significa che ‘RS = "\0"’ è lo stesso di ‘RS = ""’. (a.b.)

Capita che recenti versioni di mawk possano usare i carattere NUL come separatore di record. Comunque questo è un caso particolare: mawk non consente di includere caratteri NUL nelle stringhe. (Ciò potrebbe cambiare in una versione futura di mawk.)

Vedi Funzione readfile per un modo interessante di leggere file interi. Se si usa gawk, si veda Esempio di estensione Readfile per un’altra opzione.


Note a piè di pagina

(19)

Almeno quelle che ci sono note.


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