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. Se contiene più di un carattere, è considerato essere un’espressione regolare (vedi la sezione 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 la sezione Un semplice editor di flusso 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 la sezione Opzioni sulla riga di comando). In modalità compatibile, solo il primo carattere del valore di RS determina la fine del record.

mawk ha permesso che RS fosse un’espressione regolare da decenni. A partire dall’ottobre 2019, anche BWK awk lo permette. Nessuna delle due versioni, tuttavia, fornisce RT.

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 20 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 la sezione Leggere un intero file in una sola volta per un modo interessante di leggere file interi. Se si usa gawk, si veda Leggere un intero file in una stringa per un’altra opzione.


Note a piè di pagina

(20)

Almeno quelle che ci sono note.


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