#!/bin/bash
q=$(bc <<< "scale=2;$p*100")
head -n$q numbers.txt > secondcoordinate.txt
Isso é apenas parte do roteiro, mas acho que é o suficiente para esclarecer minhas intenções. p
é uma variável com apenas duas casas decimais, portanto q
deve ser um número inteiro... No entanto, bc
mostra, por exemplo, 10.00
em vez de 10
.
Como posso resolver isso?
Responder1
Você não pode fazer isso com o óbvio scale=0
por causa da forma como a escala é determinada.
A documentação explica indiretamente que dividir por um é suficiente para redefinir a saída para corresponder ao valor de scale
, cujo padrão é zero:
expr1 / expr2O resultado da expressão é o quociente das duas expressões. A escala do resultado é o valor da escala da variável.
p=12.34; echo "($p*100)" | bc
1234.00
p=12.34; echo "($p*100)/1" | bc
1234
Se a sua versão bc
não lidar com isso, passe-a sed
:
p=12.34; echo "($p*100)" | bc | sed -E -e 's!(\.[0-9]*[1-9])0*$!\1!' -e 's!(\.0*)$!!'
1234
Este par de REs retirará os zeros finais da parte decimal de um número. Portanto, 3,00 será reduzido para 3 e 3,10 será reduzido para 3,1, mas 300 permanecerá inalterado.
Alternativamente, use perl
e dispense bc
em primeiro lugar:
p=12.34; perl -e '$p = shift; print $p * 100, "\n"' "$p"
Responder2
você pode usar o awk para calcular os valores
bash-3.2$ p=0.01
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
1
bash-3.2$ p=0.02
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
2
bash-3.2$ p=0.022
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
2.2
Responder3
DR
Você tem muitas opções.a.C.tem um comportamento conhecido onde scale=0
nem sempre faz o que você espera, mas há muitas soluções alternativas. Aqui estão apenas alguns.
imprimir
Usarimprimirpara limitar sua saída a números inteiros.
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
bc com divisão
Se você quiser ficar coma.C.escala, você precisa especificar uma escala de zeroedivida por 1 para redefinir a escala. Esse é um comportamento conhecido, mas realmente não consigo explicar o porquê disso.
$ echo '12.34 * 100 / 1' | scale=0 bc
1234
sed
Basta retirar os caracteres finais indesejados.
$ echo '12.34 * 100' | bc | sed 's/\.00$//'
1234
festa
Use uma expansão de chaves para retornar o valor antes do decimal.
$ p='12.34'; q=$(bc <<< "scale=2; $p*100"); echo ${q%%.00}
1234
Responder4
Aqui está uma função bash para remover zeros à direita.
remove_trailing_zeroes()
{
declare -n n="$1"
# Prepend a 0 if number starts with a dot.
if [[ $n =~ ^[.] ]]; then
n="0$n"
fi
# Remove trailing zeroes
while [[ $n =~ [.].*0$ ]]; do
n="${n%0}"
done
# Remove trailing dot if any
if [[ $n =~ [.]$ ]]; then
n="${n%.}"
fi
}
Você pode então usá-lo assim para o seu caso:
q=$(bc <<< "scale=2;$p*100")
remove_trailing_zeroes q
head -n$q numbers.txt > secondcoordinate.txt