#!/bin/bash
q=$(bc <<< "scale=2;$p*100")
head -n$q numbers.txt > secondcoordinate.txt
Eso es sólo una parte del guión, pero creo que es suficiente para aclarar mis intenciones. p
es una variable con sólo dos decimales, por lo que q
debería ser un número entero... Sin embargo, bc
muestra, por ejemplo, 10.00
en lugar de 10
.
¿Como puedo resolver esto?
Respuesta1
No puedes hacer esto con lo obvio scale=0
debido a la forma en que se determina la escala.
La documentación explica indirectamente que dividir por uno es suficiente para restablecer la salida para que coincida con el valor de scale
, que por defecto es cero:
expr1/expr2El resultado de la expresión es el cociente de las dos expresiones. La escala del resultado es el valor de la escala variable.
p=12.34; echo "($p*100)" | bc
1234.00
p=12.34; echo "($p*100)/1" | bc
1234
Si su versión de bc
no maneja esto, canalícelo en sed
su lugar:
p=12.34; echo "($p*100)" | bc | sed -E -e 's!(\.[0-9]*[1-9])0*$!\1!' -e 's!(\.0*)$!!'
1234
Este par de RE eliminará los ceros finales de la parte decimal de un número. Entonces 3,00 se reducirá a 3 y 3,10 se reducirá a 3,1, pero 300 permanecerá sin cambios.
Alternativamente, utilice perl
y prescinda bc
en primer lugar de:
p=12.34; perl -e '$p = shift; print $p * 100, "\n"' "$p"
Respuesta2
puedes usar awk para calcular los 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
Respuesta3
TL;DR
Tienes muchas opciones.antes de Cristotiene un comportamiento conocido que scale=0
no siempre hace lo esperado, pero existen muchas soluciones. Éstos son sólo algunos.
imprimirf
Usarimprimirfpara limitar su salida a números enteros.
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
bc con división
Si quieres seguir conantes de Cristoescala, es necesario especificar una escala de ceroydivida por 1 para restablecer la escala. Este es un comportamiento conocido, pero realmente no puedo explicar el por qué.
$ echo '12.34 * 100 / 1' | scale=0 bc
1234
sed
Simplemente elimine los caracteres finales no deseados.
$ echo '12.34 * 100' | bc | sed 's/\.00$//'
1234
intento
Utilice una expansión de llaves para devolver el valor antes del decimal.
$ p='12.34'; q=$(bc <<< "scale=2; $p*100"); echo ${q%%.00}
1234
Respuesta4
Aquí hay una función bash para eliminar los ceros finales.
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
}
Luego puedes usarlo así para tu caso:
q=$(bc <<< "scale=2;$p*100")
remove_trailing_zeroes q
head -n$q numbers.txt > secondcoordinate.txt