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
————————————