Deixe o Tee segurar a carruagem - devolve melhor

2

Escrevi um aplicativo de console Java que imprime repetidamente seu status no console usando retornos de carro (\ r) no final, em vez de feeds de linha (\ n) para manter a saída em uma tela. Eu também quero canalizar essa saída para um arquivo, como

java -jar my-jar.jar | tee /tmp/my-jar.log

No entanto, não faz sentido escrever tudo nesse arquivo, apenas o que é visível no final do aplicativo. Em outras palavras, não preciso de todas as "linhas" que terminam com \ lá.

Exemplo: eu codifico

System.out.print("hello\r")
Thread.sleep(2000);
System.out.println("world")

"olá" aparece na tela e depois de dois segundos ele é substituído por "mundo". Portanto, depois que o programa termina, o usuário vê apenas "mundo" na tela. Tudo bem, está correto.

No entanto, se eu tee isso para um arquivo que contém "hello \ rworld \ n", mas eu só quero que ele contenha "world \ n".

Como faço isso na linha de comando em vez de codificá-lo em Java (por que a pergunta está aqui e não em SO)?

    
por sjngm 14.09.2016 / 08:39

2 respostas

2

Usando sed

Por padrão, sed lê entrada separada por nova linha. Este comando removerá tudo antes do último \r em uma linha:

sed 's/.*\r//'

Por exemplo:

$ echo $'line1\n\hi\rhello\rworld' | sed 's/.*\r//'
line1
world

Para usar isso com tee , podemos usar substituição de processo :

echo $'line1\n\hi\rhello\rworld' | tee >(sed 's/.*\r//' >Outfile)

No bash, o construtor >(...) é chamado de substituição de processo . Ele executa os comandos nos parênteses e os coloca em um objeto semelhante a um arquivo. tee escreve no objeto tipo arquivo e os comandos processam a entrada.

Usando o awk

Da mesma forma, isso remove tudo antes do último \r em uma linha separada por nova linha:

awk -F'\r' '{print $NF}'

A opção -F'\r' define o separador de campo como um retorno de carro. Consequentemente, só queremos imprimir o último campo, $NF , em cada linha separada por nova linha. Assim, print $NF .

Por exemplo:

$ echo $'line1\n\hi\rhello\rworld' | awk -F'\r' '{print $NF}'
line1
world

Para usar isso com tee :

echo $'line1\n\hi\rhello\rworld' | tee >(awk -F'\r' '{print $NF}' >Outfile)
    
por 14.09.2016 / 08:46
1

Consegui resolver um problema semelhante com col (filtrar feeds de linha reversa da entrada) .

java -jar my-jar.jar | tee >(col -pb >/tmp/my-jar.log)

EDITAR: Resposta refinada para melhor corresponder à pergunta.

    
por 12.04.2017 / 14:41