Quando os comandos são agrupados entre parênteses, o stdin para o próximo comando é coletado de todos os comandos agrupados, por exemplo
user@system:~$ (echo 1; echo 2; echo -e '3\n4') | tac
4
3
2
1
contra
user@system:~$ echo 1; echo 2; echo -e '3\n4' | tac
1
2
4
3
Existe uma maneira de fazer o inverso disso, onde o stdout de um comando vai para todos os comandos agrupados, por exemplo
user@system:~$ echo -e '1\n2\n3\n4\n5' | (tail -n2; head -n2)
4
5
1
2
Um exemplo específico útil para isso poderia ser uma tabela com um cabeçalho:
user@system:~$ cat datatable.md | (head -n2; sed '1,2d' | sort)
Em:
A saída de
cat
vai para amboshead
esed
.head
esed
compartilha o mesmo stdin, que é a extremidade de leitura do pipecat
para onde está sendo escrita.Mas a maioria das
head
implementações lê sua entrada em grandes blocos, então, provavelmente lerá mais de 2 linhas e até mesmo a entrada inteira, mesmo que esteja exibindo apenas as 2 primeiras linhas.E como a entrada é um pipe em vez de um arquivo normal, ele não pode retornar ao final dessas duas linhas na entrada, como o POSIX exige para arquivos pesquisáveis.
Aqui, concatenar um único arquivo faz pouco sentido, você pode fazer:
Desta vez, onde a entrada é um arquivo regular, ele também é pesquisável.
Também substituí o
(...)
que é para executar um subshell, pelo{ ...;}
que é para agrupar comandos, esed 1,2d|sort
por apenassort
como. Presumo que você queira classificar o restante da entrada (das linhas 3) em vez de pular 2 linhas extras (o quetail -n+3
seria mais óbvio).Se você usar um pipe, poderá substituí-lo
head
por algo que leia as duas primeiras linhas, um byte de cada vez, ou que possa ser convencido a fazer isso.Com a implementação GNU de
sed
, você pode fazer:Ou você pode fazer:
O melhor que posso pensar é algo assim:
Esse problema é resolvido trivialmente por um padrão diferente: concatenar pipes; você não precisa de "fluxos divididos" para isso.
Você obteve respostas para a pergunta específica que fez, mas se quiser classificar partes de um arquivo como no exemplo fornecido no final da sua pergunta, considere empregar uma abordagem Decorar-Classificar-Desdecorar , por exemplo, com esta entrada:
e usando qualquer versão dessas ferramentas Unix para classificar as linhas após um cabeçalho de 2 linhas:
Para ver o que isso está fazendo, remova o pipe para classificar e cortar, depois adicione a classificação novamente:
Decore (adicione informações sobre números de linha para classificar):
Classificar (classificar primeiro pelo bit "número de linha menor que 3", depois classificar os dados de entrada e, em seguida, classificar pelo número da linha original para preservar a ordem de entrada para duplicatas):
Desdecorar (remover a informação do número da linha adicionada na etapa 1):