Perl
perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
A idéia aqui é que usamos o operador módulo %
com $.
variável de número de linha , para descobrir qual é o primeiro, qual é o segundo e qual é a terceira linha. Para cada terceira linha, o restante é 0, enquanto para cada primeira e segunda linhas, ele terá números correspondentes.
Teste:
$ 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.
Melhoria menor
A abordagem para armazenar a segunda linha em uma variável tem uma falha. E se a última linha for a "segunda", ou seja, para o número restante da linha for 2? O código original da minha resposta e da DopeGhoti não será impresso My dog is orange
se deixarmos de fora a última linha. A correção para isso em ambos os casos é usar o END{}
bloco de código, desabilitando a variável temporária após a impressão. Em outras palavras:
$ 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
Dessa forma, o código funcionará para um número arbitrário de linhas em um arquivo, não apenas para as divisíveis por 3.
Correção adicional para o problema mencionado nos comentários
No caso do awk, se a última linha do arquivo produzir uma saída de 1 por $. % 3, o código anterior tem o problema de gerar nova linha em branco devido à impressão incondicional de END{print delay}
, uma vez que a print
função mencionada nos comentários sempre anexa nova linha a qualquer variável em que esteja operando. No caso da perl
versão, esse problema não ocorre, pois a função with -ne
flags print
não anexa a nova linha.
No entanto, a correção no caso do awk é tornar condicional, como mencionado por Dope Ghoti nos comentários, é verificar o tamanho da variável temporária. A versão perl da mesma correção seria:
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s if length $s}' input.txt