Anexar a um cano e passar adiante?

Anexar a um cano e passar adiante?

Eu tenho uma função bash simples dividindo dois números:

echo "750/12.5" | bc

Eu gostaria de pegar a saída bce anexar /24e canalizar o resultado para outra instância de bc.

Algo como:

echo "750/12.5" | bc | echo $1 + "/24" | bc

Onde $1está o resultado canalizado.

PS: Sei que poderia fazer echo "750/12.5/24" | bcminha pergunta mais em relação ao acréscimo de texto a um resultado de canal.

Responder1

Consegui isso usando sede substituindo o final da linha:

echo "my text" | sed 's/$/ more text/'

Retorna:

my text more text

Seu exemplo:

echo "750/12.5" | bc | sed 's/$/\/24/' | bc

Responder2

Abordagem alternativa:

TL;DR: Use catpara concatenar com stdin( -) como argumento. Observe que isso separará seus fluxos concatenados em novas linhas; remova se indesejado.

Infelizmente, essa abordagem é um pouco complicada para o seu caso de uso específico, pois bcfalha se houver uma nova linha no meio da expressão:

$ echo "750/12.5" | bc | cat - <(echo "/24") | bc
60
(standard_in) 2: parse error

Você pode contornar isso excluindo a nova linha do bcresultado original:

$ echo "750/12.5" | bc | tr -d '\n' | cat - <(echo "/24") | bc
2

No entanto, me deparei com essa questão pesquisando "bash anexado ao pipe" no Google e, no meu caso, na verdadefazerquero essa nova linha entre as concatenações. Então, para aqueles que estão aqui pelo mesmo motivo, use | cat - <(...):

$ echo foo | cat - <(echo bar)
foo
bar
$ echo foo | cat - <(echo bar) | sort | cat - <(echo last_line)
bar
foo
last_line
$ echo foo | cat - <(echo bar) | sort | cat <(echo header) - <(echo last_line)
header
bar
foo
last_line

Responder3

Na opção mais simples, isso é anexado ao fluxo do tubo:

$ echo "750/12.5" | { bc; echo "/24"; }
60
/24

No entanto, isso tem uma nova linha inesperada, para evitar que você precise usar tr:

$ echo "750/12.5" | { bc | tr -d '\n' ; echo "/24"; }
60/24

Ou, dado o fato de que uma expansão de comando remove novas linhas à direita:

$ printf '%s' $( echo "750/12.5" | bc ); echo "/24"
60/24

Mas provavelmente, a maneira correta deveria ser semelhante a:

$ echo "$(echo "750/12.5" | bc )/24"
60/24

Que, para ser usado em bc, poderia ser escrito assim:

$ bc <<<"$(bc <<<"750/12.5")/24"
2

O que, para obter uma precisão razoável de número flutuante, deve ser algo como:

$ bc <<<"scale=10;$(bc <<<"scale=5;750/12.5")/24"
2.5000000000

Observe a necessidade de duas escalas, pois existem duas instâncias de bc.

É claro que uma instância de bc precisa apenas de uma escala:

$ bc <<<"scale=5;750/12.5/24"

Na verdade, o que você deveria estar pensando é em termos de uma string:

$ a=$(echo "750/12.5")        # capture first string.
$ echo "$a/24" | bc           # extend the string
2

O comentário sobre a escala acima ainda é válido aqui.

Responder4

Você pode usar awkpara inserir/anexar qualquer coisa ao pipe:

$ date | awk 'BEGIN{print "prefix line"} {print}  END{print "suffix  line"}'
prefix line
Mo 21. Aug 15:24:30 CEST 2023
suffix  line

onde

  • date- é o seu canal de entrada (data atual, por exemplo aqui)
  • BEGIN{print "prefix line"}- este bloco irá inserir a saída antes do principal
  • {print}- imprime o conteúdo do pipe de entrada; alguém poderia fazer algum processamento aqui, se necessário
  • END{print "suffix line"} - anexa a saída após main

Para fazer o mesmo em linha única, basta usar printf:

$ date | awk 'BEGIN{printf("prefix line >> ")} {printf($0)}  END{printf(" << suffix  line")}'
prefix line >> Mo 21. Aug 15:32:08 CEST 2023 << suffix  line/upload/sc505enb/tmp>

$ echo "750/12.5" | bc | awk '{printf($0)}  END{printf("/24\n")}'
60/24

informação relacionada