Perl
perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
L'idea qui è che usiamo l'operatore modulo %
con la $.
variabile del numero di riga , per capire quale è ogni primo, quale è ogni secondo e quale è ogni 3a riga. Per ogni 3a riga il resto è 0, mentre per ogni 1a e 2a riga avrà numeri corrispondenti.
Test:
$ cat input.txt
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
$ perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
Piccolo miglioramento
L'approccio con la memorizzazione della seconda riga in una variabile ha un difetto. Cosa succede se l'ultima riga è la "seconda", ovvero per quel resto di numero di riga è 2? Il codice originale nella risposta my e DopeGhoti non verrà stampato My dog is orange
se tralasciamo l'ultima riga. La soluzione per questo in entrambi i casi è l'uso del END{}
blocco di codice, con la disattivazione della variabile temporanea dopo la stampa. In altre parole:
$ awk 'NR%3 == 1 { print } NR%3 == 2 { delay=$0 } NR%3 == 0 { print; print delay;delay=""}END{print delay}' input.txt
e
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s}' input.txt
In questo modo, il codice funzionerà per un numero arbitrario di righe in un file, non solo per quelle divisibili per 3.
Correzione aggiuntiva per il problema menzionato nei commenti
Nel caso di awk, se l'ultima riga nel file produce un output di 1 per $. % 3, il codice precedente ha emesso un problema di emissione di una nuova riga vuota a causa della stampa incondizionata di END{print delay}
, poiché la print
funzione menzionata nei commenti aggiunge sempre una nuova riga a qualunque variabile su cui sta operando. In caso di perl
versione questo problema non si verifica, poiché con la funzione -ne
flags print
non si aggiunge la nuova riga.
Tuttavia, la soluzione nel caso di awk è quella di rendere condizionale, come indicato da Dope Ghoti nei commenti, è verificare la lunghezza della variabile temporanea. La versione perl della stessa correzione sarebbe:
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s if length $s}' input.txt