lunedì 22 ottobre 2012

Un po' di AWK. Ottava parte

Eccoci all'ottava puntata del sequel "Un po' di AWK". Ma chi me lo doveva dire...
Dovete sapere che queste mie peripezie su AWK sono seguite anche da mio nonno e dal caro amico Ciro, che di mestiere fa il pastore.
 Mio nonno e Ciro sono persone molto esigenti nel senso che, se mi perdo in teorie, si incazzano come delle bestie feroci. Ma non è finita qui.
Ultimamente mio nonno vuole che, prima di pubblicare un post su awk, sia letto da lui; e solo se mi dà l'imprimatur lo posso pubblicare. Vabbè, lasciamo stare...


Continuiamo con le variabili predefinite di AWK. Finora abbiamo parlato approfonditamente solo di FS. (qui e qui), mentre le altre variabili Built-in le abbiamo toccate solo di striscio. Ok, rimediamo!

OFS
Giusto per capirci con poche battute, potremmo dire che, mentre FS è un separatore di campo in entrata, OFS è un separatore di campo in uscita. Passiamo agli esempi...che è meglio!

Supponiamo di avere il seguente testo:

banane;pere;ciliegie;fragole;

Bene! Questo è il testo che AWK dovrà leggere. Sappiamo già che il separatore di campo predefinito di AWK è uno spazio. Ma in questo testo ne vedete spazi? Evidentemente no! Allora dobbiamo settare la variabile FS sostituendo lo spazio con il punto e virgola ";". Chiaro?

Si, perchè FS è il separatore di campo in entrata...

FS non settato:

$ echo "banane;pere;ciliegie;fragole" | awk '{print $1,$3}'

Risultato: banane;pere;ciliegie;fragole

Nell'esempio di cui sopra abbiamo chiesto ad AWK di stampare a video il primo e il terzo campo. Ma le cose non sono andate secondo le nostre intenzioni. Perchè? Ovvio, i campi non sono divisi da spazi, ma da punti e virgole. Urge perciò settare FS.

FS settato:

$ echo "banane;pere;ciliegie;fragole" | awk -F";" '{print $1,$3}'

Risultato: banane ciliegie

Se FS si occupa di come il testo deve essere letto da AWK, OFS si occupa di come il testo deve essere "sfornato", stampato, mostrato, formattato in uscita.

Facciamo qualche esempio:

Voglio che i primi tre campi del seguente testo "banane;pere;ciliegie;fragole" siano legati da un underscore.

$ echo "banane;pere;ciliegie;fragole" | awk -F";" 'BEGIN { OFS="_" } {print $1,$2,$3}'

Risultato: banane_pere_ciliegie

Qualcuno potrebbe obiettare e dire, "Ma è inutile settare OFS, basterebbe fare così!"

cioè così:

$ echo "banane;pere;ciliegie;fragole" | awk -F";" '{print $1,"_",$2,"_",$3}'

E invece non va bene!! Ecco cosa succederebbe:

Risultato: banane _ pere _ ciliegie

Avete visto? Non va bene, vero?

Giusto per fare un altro esempio. Per dividere gli stessi campi da una chiocciolina "@":

$ echo "banane;pere;ciliegie;fragole" | awk -F";" 'BEGIN { OFS="@" } {print $1,$2,$3}'

Risultato: banane@pere@ciliegie

Penso che si sia capito qual è il compito cui è preposta la variabile OFS...

Resta da dire un'ultima cosa. Il valore predefinito di OFS è uno spazio! Ok, scusa, era un dato scontato...

NF
NF è una variabile che ci dice il numero di campi in cui è diviso il record corrente.

FS non settato:

$ echo "banane;pere;ciliegie;fragole" | awk '{print NF}'

Risultato: un solo campo.

FS settato:

$ echo "banane;pere;ciliegie;fragole" | awk -F";" '{print NF}'

Risultato: Quattro campi.

Chiarissimo, vero?

La prossima volta parleremo di records, quindi delle variabili RS, ORS e NR. E ci sarà da  divertirsi col nonno e con l'amico Ciro; infatti l'argomento non è mica facile...

Alla prossima!

NB1: Vi ricordo che l'indice di "Un po' di AWK" lo potete trovare qui. Così risulterà meno difficile seguire le mie imprese catastrofiche.

NB2: Vi ricordo ancora che Io e Juhan stiamo portando avanti un minicorso su Python il cui indice lo potete trovare qui. E la cosa bella è che presto avremo post su Python firmati dal mitico e inossidabile e ineguagliabile, nonchè amico caro, Lightuono!!! :D


Nessun commento:

Posta un commento