Successivo: Campi di un solo carattere, Precedente: Separatori di campo di default, Su: Separatori di campo [Contenuti][Indice]
La precedente sottosezione
ha illustrato l’uso di caratteri singoli o di stringhe semplici come
valore di FS
.
Più in generale, il valore di FS
può essere una stringa contenente
qualsiasi espressione regolare. Se questo è il caso, ogni corrispondenza nel
record con l’espressione regolare separa campi. Per esempio, l’assegnamento:
FS = ", \t"
trasforma ogni parte di una riga in input che consiste di una virgola seguita da uno spazio e una tabulazione in un separatore di campo.
Per un esempio meno banale di espressione regolare, si provi a usare spazi
singoli per separare campi nel modo in cui sono usate le virgole. FS
può essere impostato a "[ ]"
(parentesi quadra sinistra, spazio,
parentesi quadra destra). Quest’espressione regolare corrisponde a uno spazio
singolo e niente più. (vedi la sezione Espressioni regolari).
C’è una differenza importante tra i due casi di ‘FS = " "’
(uno spazio singolo) e ‘FS = "[ \t\n]+"’
(un’espressione regolare che individua uno o più spazi, tabulazioni o
ritorni a capo). Per entrambi i valori di FS
, i campi sono
separati da serie (ricorrenze adiacenti multiple) di spazi, tabulazioni
e/o ritorni a capo. Comunque, quando il valore di FS
è
" "
, awk
prima toglie lo spazio vuoto iniziale e finale
dal record e poi stabilisce dove sono i campi.
Per esempio, la seguente pipeline stampa ‘b’:
$ echo ' a b c d ' | awk '{ print $2 }' -| b
Invece la pipeline che segue stampa ‘a’ (notare lo spazio extra intorno a ogni lettera):
$ echo ' a b c d ' | awk 'BEGIN { FS = "[ \t\n]+" } > { print $2 }' -| a
In questo caso, il primo campo è nullo, o vuoto.
Il taglio degli spazi vuoti iniziale e finale ha luogo anche
ogniqualvolta $0
è ricalcolato.
Per esempio, si consideri questa pipeline:
$ echo ' a b c d' | awk '{ print; $2 = $2; print }' -| a b c d -| a b c d
La prima istruzione print
stampa il record così come è stato letto,
con lo spazio vuoto intatto. L’assegnamento a $2
ricostruisce
$0
concatenando insieme $1
fino a $NF
,
separati dal valore di OFS
(che è uno spazio per default).
Poiché lo spazio vuoto iniziale è stato ignorato quando si è trovato
$1
, esso non fa parte del nuovo $0
. Alla fine, l’ultima
istruzione print
stampa il nuovo $0
.
C’è un’ulteriore sottigliezza da considerare quando si usano le espressioni
regolari per separare i campi.
Non è ben specificato nello standard POSIX, né altrove, cosa
significhi ‘^’ nella divisione dei campi. Il ‘^’ cerca
corrispondenze solo all’inizio dell’intero record? Oppure ogni separatore di
campo è una nuova stringa? Di fatto versioni differenti di awk
rispondono a questo quesito in modo diverso, e non si dovrebbe far affidamento
su alcun comportamento specifico nei propri programmi.
(a.b.)
Di sicuro, BWK awk
individua con ‘^’
solo l’inizio del record. Anche gawk
funziona in questo modo. Per esempio:
$ echo 'xxAA xxBxx C' | > gawk -F '(^x+)|( +)' '{ for (i = 1; i <= NF; i++) > printf "-->%s<--\n", $i }' -| --><-- -| -->AA<-- -| -->xxBxx<-- -| -->C<--
Successivo: Campi di un solo carattere, Precedente: Separatori di campo di default, Su: Separatori di campo [Contenuti][Indice]