GUIDA AD AWK, 05 – join righe

Join di righe

 

Per comprendere i prossimi comandi è necessario aprire un inciso su printf
————————————–
Inciso su printf:
è una funzione del linguaggio C, che sostanzialmente stampa a schermo un determinato output in un determinato formato

Specificatori di formato:
%i or %d -> int (intero)
%c -> char (un carattere)
%f -> float (numero con virgola )
%s -> string (stringa)

Caratteri di escape:
\n -> newline
\t -> tab
\b -> backspace
\r -> ritorno carrello

Con numeri:
%d -> stampa come decimale intero
%6d -> stampa come decimale intero con una lunghezza di almeno 6 caratteri
%f -> stampa con virgola flottante
%4f -> stampa con virgola flottante con una lunghezza di almeno 4 caratteri
%.4f -> stampa con virgola flottante con una precisione di 4 caratteri dopo la virgola (decimali)
%3.2f -> stampa con virgola flottante di almeno 3 caratteri e 2 caratteri dopo la virgola (decimali)

Con stringhe:
%s:\n -> stampa e vai a capo
%8s:\n -> stampa la stringa con lunghezza minima di 8 caratteri. Se la stringa è più piccola i restanti caratteri saranno riempiti con whitespace
%.8s:\n -> stampa solamente 8 caratteri della stringa
%-8s:\n -> stampa ALMENO 8 caratteri della stringa
—————————————–

$ cat lista1
 HEADER
 pippo
 pluto
 paperino
 HEADER
 roma
 parigi
 newyork
 HEADER
 acqua
 terra
 fuoco
$ awk '/HEADER/{if (NR!=1)print "";next}{printf $0}END{print "";}' lista1
 pippoplutopaperino
 romapariginewyork
 acquaterrafuoco

Studiamo questo comando.
Vogliamo fare il join di tutte le righe che seguono il pattern “HEADER”
/HEADER/ -> cerca le linee contenenti “HEADER”
{if (NR!=1)print “”;next} -> si attiva solo se la riga contiene “HEADER”. Stampa una linea vuota (print “”) ad eccezione della prima riga (NR!=1). Senza questa condizione una linea vuota verrebbe stampata all’inizio dell’output. Lo statement “next” indica ad awk di stoppare il processamento della riga e di passare alla riga successiva. Fino a qui, quindi, abbiamo detto ad awk di stampare una riga vuota per tutte le ricorrenze “HEADER”, ad eccezione che per la prima riga.
{printf $0} -> sarà vera per tutte le ricorrenze che NON contengono “HEADER”, per effetto di “next”. Stampa la linea senza andare a capo (printf anzichè print). Come risultato avremo tutte le righe dopo il pattern “HEADER” stampate nella stessa riga
END{print “”;} -> stampa una nuova riga alla fine (senza avremmo l’output sulla stessa riga del prompt

Se vogliamo che i campi dell’output siano divisi da uno spazio:

$ awk '/HEADER/{if (NR!=1)print "";next}{printf "%s ", $0}END{print "";}' lista1
 pippo pluto paperino
 roma parigi newyork
 acqua terra fuoco

{printf “%s “, $0} -> il valore di $0 lo stampi con lo specificatore di formato “%s “, ovvero il valore stringa di $0 stesso seguito da uno spazio

Se invece vogliamo che il delimitatore sia la virgola:

$ awk '/HEADER/{if (x)print x;x="";next}{x=(!x)?$0:x","$0;}END{print x;}' lista1
 pippo,pluto,paperino
 roma,parigi,newyork
 acqua,terra,fuoco

Utilizziamo la variabile “x” per storare l’intera stringa e stampiamo il valore di “x” ogni volta che viene matchato il pattern:
/HEADER/{if (x)print x;x=””;next} -> quando viene matchato “HEADER” se x esiste stampane il valore altrimenti impostala a null. next: passa alla riga successiva.
{x=(!x)?$0:x”,”$0;} -> se x è nullo assegna a x la riga corrente, altrimenti fai seguire a x una virgola e la riga corrente.
In tal modo x conterrà le righe unite da una virgola.
Visto che l’istruzione di stampa a schermo si trova all’interno delle graffe del match con “HEADER”, per stampare l’ultimo valore di x, viene aggiunta l’istruzione:
END{print x;} -> stampa il valore di x prima di uscire.

Ovviamente se si vuole che anche HEADER venga stampato, è sufficiente togliere il “next”:

$ awk '/HEADER/{if (x)print x;x="";}{x=(!x)?$0:x","$0;}END{print x;}' lista1
 HEADER,pippo,pluto,paperino
 HEADER,roma,parigi,newyork
 HEADER,acqua,terra,fuoco

In ultima, se vogliamo che HEADER non sia unito al resto della stringa, lo possiamo far stampare separatamente dal valore di x:

$ awk '/HEADER/{if (x)print x;print;x="";next}{x=(!x)?$0:x","$0;}END{print x;}' lista1
 HEADER
 pippo,pluto,paperino
 HEADER
 roma,parigi,newyork
 HEADER
 acqua,terra,fuoco

————————————

INDICE

Lascia una risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>