Estou obtendo saída de um programa que primeiro produz uma linha que é um monte de cabeçalhos de coluna e, em seguida, um monte de linhas de dados. Quero cortar várias colunas dessa saída e visualizá-la classificada de acordo com várias colunas. Sem os cabeçalhos, o corte e a classificação são facilmente realizados através da -k
opção de sort
acompanhar cut
ou awk
visualizar um subconjunto das colunas. No entanto, esse método de classificação combina os cabeçalhos das colunas com o restante das linhas de saída. Existe uma maneira fácil de manter os cabeçalhos no topo?
text-processing
sort
table
jonderry
fonte
fonte
{ head -1; sort; }
funcionar. Ele sempre exclui um monte de texto após a primeira linha. Alguém sabe por que isso acontece?head
está lendo mais de uma linha em um buffer e jogando a maior parte fora. Minhased
ideia teve o mesmo problema.lseek
entrada capaz, portanto não funciona ao ler de um tubo. Ele vai funcionar se você redirecionar para um arquivo>outfile
e execute{ head -n 1; sort; } <outfile
Respostas:
Roubar a ideia de Andy e transformá-la em uma função para facilitar o uso:
Agora eu posso fazer:
fonte
ps -C COMMAND
pode ser mais apropriado quegrep COMMAND
, mas é apenas um exemplo. Além disso, você não pode usar-C
se também tiver usado outra opção de seleção como-U
.body
? Como embody sort
oubody grep
. Pensamentos?header
parabody
, porque você está fazendo a ação no corpo. Espero que isso faça mais sentido.body
todos os participantes subsequentes do pipeline:ps -o pid,comm | body grep less | body sort -k1nr
<foo body sort -k2
oubody sort -k2 <foo
. Apenas um caractere extra do que você queria.Você pode manter o cabeçalho no topo assim com o bash:
Ou faça-o com perl:
fonte
{}
ok em vez de()
?IFS=
desativa a divisão de palavras ao ler a entrada. Eu não acho que é necessário ao ler$REPLY
.echo
irá expandir as barras invertidas sexpg_echo
estiver definido (não o padrão);printf
é mais seguro nesse caso.echo $REPLY
sem aspas condensará espaços em branco; Eu acho queecho "$REPLY"
deveria ficar bem.read -r
será necessário se a entrada puder conter escapes de barra invertida. Parte disso pode depender da versão do bash.read REPLY; echo $REPLY
(retira espaços à esquerda) eread; echo $REPLY
(não).xpg_echo
depende do seu sistema, por exemplo, no Solaris, acho que o padrão é verdadeiro. É por isso que Gilles gostaprintf
tanto: é a única coisa com comportamento previsível.Encontrei uma boa versão do awk que funciona muito bem em scripts:
fonte
sort
comando externamente? Alguém conhece pelo menos um link para uma página que explica o uso de pipe no awk?Hackish, mas eficaz: preceda
0
todas as linhas do cabeçalho e1
todas as outras linhas antes da classificação. Retire o primeiro caractere após a classificação.fonte
Aqui estão alguns ruídos mágicos da linha perl nos quais você pode canalizar sua saída para classificar tudo, mas manter a primeira linha no topo:
perl -e 'print scalar <>, sort <>;'
fonte
Tentei a
command | {head -1; sort; }
solução e posso confirmar que realmente estraga tudo -head
lê em várias linhas do tubo e depois produz apenas o primeiro. Portanto, o restante da saída, quehead
não leu, é passado para -sort
NÃO o restante da saída começando na linha 2!O resultado é que faltam linhas (e uma linha parcial!) Que estavam no início de sua saída de comando (exceto que você ainda possui a primeira linha) - um fato que é fácil de confirmar adicionando um canal
wc
no final de o pipeline acima - mas isso é extraordinariamente difícil de rastrear se você não sabe disso! Passei pelo menos 20 minutos tentando descobrir por que tinha uma linha parcial (primeiros 100 bytes mais ou menos cortados) na minha saída antes de resolvê-la.O que acabei fazendo, que funcionou lindamente e não exigiu a execução do comando duas vezes, foi:
Se você precisar colocar a saída em um arquivo, poderá modificá-lo para:
fonte
head
oline
utilitário interno do ksh93 ou o utilitário (em sistemas que ainda possuem um) ougnu-sed -u q
ouIFS=read -r line; printf '%s\n' "$line"
, que leem a entrada um byte por vez para evitar isso.Eu acho que isso é mais fácil.
ou isso que é possivelmente mais rápido, pois não cria um sub shell
Outros usos legais
embaralhar linhas após a linha do cabeçalho
reverter linhas após a linha do cabeçalho
fonte
cat file | { head -n 1 ; sort ; } > file2
só mostram cabeçafonte
command
duas vezes. Portanto, é limitado a alguns comandos específicos. No entanto, para ops
comando solicitado no exemplo, ele funcionaria.Simples e direto!
fonte
command
duas vezes. Portanto, não é realmente adequado para uso em um pipeline.Eu vim aqui procurando uma solução para o comando
w
. Este comando mostra detalhes de quem está conectado e o que está fazendo.Para mostrar os resultados classificados, mas com os cabeçalhos mantidos no topo (existem duas linhas de cabeçalhos), decidi:
Obviamente, isso executa o comando
w
duas vezes e, portanto, pode não ser adequado para todas as situações. No entanto, para sua vantagem, é substancialmente mais fácil de lembrar.Note que o
tail -n +3
meio 'mostra todas as linhas a partir do 3º em diante' (vejaman tail
para detalhes).fonte
Tente fazer:
fonte