Estou montando uma apresentação para um público não técnico. Eu tenho um programa em execução no bash que gera um fluxo contínuo de valores, alguns dos quais são importantes. Gostaria de destacar os resultados importantes à medida que são exibidos para que o público possa ter uma idéia de sua frequência. O problema é que não consigo sed
operar em um fluxo em execução. Funciona bem se eu colocar os resultados em um arquivo, como em:
cat output.txt | sed "s/some text/some text bolded/"
Mas se eu tentar a mesma coisa na saída em execução, assim:
command | sed "s/some text/some text bolded/"
sed
faz nada. Alguma ideia?
Como Lambert foi útil o suficiente para apontar, o fato de eu dizer que sed
não faz nada era vago. O que está acontecendo é que o programa gera stdout
(tenho certeza de que não está gravando stderr
) como faria normalmente, mesmo que seja canalizado sed
.
A questão parece ser que o comando chama um segundo programa, que emite para stdout. Existem algumas linhas impressas pelo primeiro programa; estes eu posso editar. Depois, há um fluxo de valores impresso pelo segundo programa; estes eu não posso editar.
Os métodos Perl e awk também não funcionam.
fonte
stdbuf -o0 command | sed "s/some text/some text bolded/"
?command|egrep 'some text|$'
g
substituição "global" obtida, caso contrário, somente a primeira ocorrência em uma linha será substituída:sed "s/old/new/g"
Respostas:
As chances são de que a saída do comando seja armazenada em buffer. Quando o comando grava em um terminal, o buffer é liberado em cada nova linha, para que você apareça na taxa esperada. Quando o comando grava em um canal, o buffer é liberado apenas quando atinge alguns kilobytes, portanto fica muito atrasado. Assim é o comportamento padrão da biblioteca de entrada / saída padrão.
Para forçar o comando a não armazenar sua saída, você pode usar
unbuffer
(da expectativa) oustdbuf
(do GNU coreutils).fonte
stdbuf
não funcionou (foi mencionado anteriormente, BTW), masunbuffer
funcionou !! Você não tem idéia do quão feliz você me deixou.sed
em si usa esse buffer (cf post ChennyStar), portanto, os exemplos aqui podem não funcionar, poissed
é ocommand
to buffer:cat /etc/passwd | unbuffer sed
massed
ele possui uma-u
opção, portantogrep
pode ser mais adequado nesses exemplos. Muito obrigado pela sua informação de fundo! Ótima resposta!sed
tem uma opção para isso:Que carrega quantidades mínimas de dados dos arquivos de entrada e libera os buffers de saída com mais frequência. Veja
man sed
para mais detalhes.fonte
sed
Somente GNU (não BSDsed
), e acredito que isso ainda não impediria o buffer do comando no início do pipe. Mas bom mencionar isso. :)Eu usaria awk
Onde
/some important stuff/
selecione uma linha importante, como no sedprintf "%c[31m%s%c[0m\n",27,$0,27 ;
imprimir em vermelhoo ponto principal é que
command
deve liberar as linhas, mas esse deve ser o caso se você tiver muita saída.fonte
awk
(usingsub()
orgsub()
), no caso dessa substituição primitivased
é certamente a ferramenta apropriada.O caminho perl:
ou com uma saída contínua:
Um script bash para a saída
cont
:Teste com:
\x1b[1m
- intensidade arrojada ou aumentada${1}
- o backreferenze\x1b[0m
- redefinir todos os atributosResultado:
Mais códigos de escape aqui .
fonte