cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
O problema de traduzir isso para algo que usa tailé que você tailprecisa ler o arquivo inteiro para encontrar o final dele. Para usar isso em seu pipeline, você precisa
- Forneça o conteúdo completo do documento para
tail.
- Forneça novamente para
cat.
- Naquela ordem.
A parte complicada não é duplicar o conteúdo do documento ( teeisso é possível), mas fazer com que a saída tailocorra antes da saída do restante do documento, sem usar um arquivo temporário intermediário.
O uso sed(ou awk, como John1024 faz ) se livra da análise dupla dos dados e do problema de pedido armazenando os dados na memória.
A sedsolução que proponho é
1{h;d;}, armazene a primeira linha no espaço em espera, como está, e pule para a próxima linha.
H, acrescente uma à outra linha ao espaço de espera com uma nova linha incorporada.
${G;p;}, acrescente o espaço de espera à última linha com uma nova linha incorporada e imprima os dados resultantes.
Esta é uma tradução literal da solução de John1024 sed, com a ressalva de que o padrão POSIX apenas garante que o espaço de espera seja de no mínimo 8192 bytes (8 KiB; mas recomenda que esse buffer seja alocado e expandido dinamicamente conforme necessário, que ambos GNU sede BSD sedestá fazendo).
Se você se permitir usar um pipe nomeado:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
Isso usa teepara enviar os dados para baixo mypipee ao mesmo tempo para cat. O catutilitário primeiro lerá a saída de tail(que lê de mypipe, para o qual teeestá gravando) e, em seguida, anexará a cópia do documento proveniente diretamente tee.
Porém, há uma falha séria nisso: se o documento for muito grande (maior que o tamanho do buffer do tubo), ele estará teegravando mypipee catbloqueando enquanto aguarda que o tubo (sem nome) seja esvaziado. Não seria esvaziado até ser catlido. catnão leria até tailterminar. E tailnão iria terminar até teeterminar. Essa é uma situação clássica de conflito.
A variação
tee >( tail -n 1 >mypipe ) | cat mypipe -
tem o mesmo problema.