Print / Tee para consola sem passar a saída para o tubo

1

Existe uma maneira de imprimir ou colocar uma coisa no console e ainda passar outra coisa para o próximo canal? Algo como:

echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev

que resultaria em:

PUTTING MY THING DOWN
FLIP IT
tac

EDIT: Isso também deve funcionar com entrada de múltiplas linhas:

printOrWhatNot() {...}

seq 10 30 |printOrWhatNot searching for 3s | grep 3

produziria

searching for 3s
13
23
30

A resposta de Lars pareceu passar apenas pela primeira entrada (aqui seria 10 )

Idealmente, a saída seria incorporada durante o processamento, o que não era o que eu estava vendo com a resposta de Glen. Então

seq 10 30 |tee /dev/tty |printOrWhatNot searching for 3s | grep 3

contribuiria para:

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
searching for 3s
13
23
30
    
por Chris 28.10.2012 / 04:17

2 respostas

2

Não tenho conhecimento de nenhum comando padrão para esse propósito, mas é fácil criar um próprio em um pequeno script de shell. Crie o seguinte, torne-o executável e adicione sua localização ao seu PATH.

Editar - atualizado para manipular entrada padrão de várias linhas e para manipular espaços na entrada.

printOrWhatnot:

 #!/bin/bash
 # printOrWhatnot script, to re-pipe stdin, while echoing something else via stderr

 # read stdin (possibly multi-lined) into $my_array[]:
 while read -t 1  piped
 do
    my_array=("${my_array[@]}" "$piped")
 done

 # echo the supplied arguments by sending them to stderr:
 echo "$@" 1>&2

 # now spew $my_array[], line by line, to any further processing:
 arrayLen=${#my_array[@]}
 for (( i=0; i<$arrayLen; i++ ));
 do
    echo ${my_array[$i]}
 done

Agora, deve funcionar exatamente como você sugeriu:

 myhost> echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev
 PUTTING MY THING DOWN
 FLIP IT
 tac
    
por 28.10.2012 / 07:15
2

Você precisa enviar sua mensagem para um descritor de arquivo diferente do stdout e apenas descartar stdin para stdout intocado:

printOrWhatnot() { echo "$@" >&2; cat -; }

Se você precisar que suas mensagens (eventualmente) apareçam no stdout, altere rev para rev 2>&1 ou coloque seu pipeline entre chaves:

{
    echo dog | 
    printOrWhatnot "PUTTING MY THING DOWN" | 
    sed 's/dog/cat/g' | 
    printOrWhatnot "FLIP IT" |
    rev
} 2>&1 
    
por 28.10.2012 / 14:10