Estoy tratando de comparar dos números de coma flotante dentro de un script bash. Tengo que variables, por ejemplo
let num1=3.17648e-22
let num2=1.5
Ahora, solo quiero hacer una comparación simple de estos dos números:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
Desafortunadamente, tengo algunos problemas con el tratamiento correcto de num1 que puede ser del "formato e". :(
Cualquier ayuda, sugerencias son bienvenidas!
Respuestas:
Más convenientemente
Esto se puede hacer más convenientemente usando el contexto numérico de Bash:
Explicación
La canalización a través del comando de la calculadora básica
bc
devuelve 1 o 0.La opción
-l
es equivalente a--mathlib
; carga la biblioteca matemática estándar.El encerrar la expresión completa entre paréntesis dobles
(( ))
traducirá estos valores a verdadero o falso respectivamente.Por favor, asegúrese de que
bc
esté instalado el paquete básico de la calculadora.Esto también funciona para carrozas en formato científico, siempre que
E
se utilice una letra mayúscula , por ejemplonum1=3.44E6
fuente
bc
instalado el paquete de la calculadora.0: not found
con la declaraciónif (( $(echo "$TOP_PROCESS_PERCENTAGE > $THRESHOLD" | bc -l) )); then
.bc
en comillas inversas o$()
luego en(( ))
... es decir(( $(bc -l<<<"$a>$b") ))
y no(( bc -l<<<"$a>$b" ))
.E
, y todos los errores de sintaxis desaparecerán.bash maneja solo matemáticas enteras, pero puede usar el
bc
comando de la siguiente manera:Tenga en cuenta que el signo exponente debe estar en mayúscula
fuente
bc
herramienta y eso es lo que recomendaría a cualquier programador de BASH. BASH es lenguaje sin tipo. Sí, puede hacer aritmética de enteros, pero para el punto flotante debe usar alguna herramienta externa. BC es el mejor porque para eso está hecho.Es mejor usarlo
awk
para matemáticas no enteras. Puede usar esta función de utilidad bash:Y llámalo como:
fuente
awk
ybc
en scripts de shell es una práctica estándar desde la antigüedad, diría que algunas funciones nunca se han agregado a los shells porque están disponibles en awk, bc y otras herramientas de Unix. No hay necesidad de pureza en los scripts de shell.exit
que Awk comunique el resultado al shell de una manera adecuada y legible por máquina.if awk -v n1="123.456" -v n2="3.14159e17" 'BEGIN { exit (n1 <= n2) }' /dev/null; then echo bigger; else echo not; fi
... aunque tenga en cuenta cómo se invierte la condición (el estado de salida 0 significa éxito en el shell).python
? Se haperl
instalado por defecto en muchos sistemas Linux / Unix ... inclusophp
tambiénawk
solución es más sólida en mi caso que labc
que arroja resultados incorrectos por una razón que no obtuve.Solución de bash pura para comparar flotadores sin notación exponencial, ceros iniciales o finales:
El orden de los operadores lógicos es importante . Las partes enteras se comparan como números y las partes fraccionarias se comparan intencionalmente como cadenas. Las variables se dividen en partes enteras y fraccionarias utilizando este método .
No comparará flotantes con enteros (sin punto).
fuente
puede usar awk combinado con una condición bash if, awk imprimirá 1 o 0 y estos se interpretarán mediante la cláusula if con verdadero o falso .
fuente
if (( $(echo $d1 $d2 | awk '{if ($1 > $2) print 1;}') )); then echo "yes"; else echo "no"; fi
tenga cuidado al comparar números que son versiones de paquetes, como verificar si grep 2.20 es mayor que la versión 2.6:
Resolví tal problema con dicha función shell / awk:
fuente
dpkg --compare-versions
menudo es útil. Tiene la lógica completa para comparar las versiones de paquetes de Debian incorporadas, que son más complejas que simplementex.y
.Por supuesto, si no necesita realmente la aritmética de coma flotante, solo la aritmética en, por ejemplo, valores de dólar donde siempre hay exactamente dos dígitos decimales, puede simplemente soltar el punto (multiplicando efectivamente por 100) y comparar los enteros resultantes.
Obviamente, esto requiere que esté seguro de que ambos valores tienen el mismo número de lugares decimales.
fuente
Usé las respuestas de aquí y las puse en una función, puedes usarlas así:
Una vez llamado,
echo $result
será1
en este caso, de lo contrario0
.La función:
O una versión con salida de depuración:
Simplemente guarde la función en un
.sh
archivo separado e inclúyalo así:fuente
Estaba publicando esto como respuesta a https://stackoverflow.com/a/56415379/1745001 cuando se cerró como un duplicado de esta pregunta, así que aquí está como se aplica aquí también:
Por simplicidad y claridad, simplemente use awk para los cálculos, ya que es una herramienta estándar de UNIX y es tan probable que esté presente como bc y mucho más fácil de trabajar sintácticamente.
Para esta pregunta:
y para esa otra pregunta que se cerró como duplicación de esta:
fuente
awk
y herramientas como esta (te estoy mirandosed
...) deberían relegarse al basurero de los proyectos antiguos, con un código que todo el mundo tiene demasiado miedo de tocar, ya que fue escrito en un lenguaje de nunca lectura.O usted es el proyecto relativamente raro que necesita priorizar la optimización del uso de la CPU sobre la optimización del mantenimiento del código ... en cuyo caso, continúe.
Si no es así, ¿por qué no usar algo legible y explícito, como
python
? Tus compañeros codificadores y tu futuro yo te lo agradecerán. Puede usar enpython
línea con bash como todos los demás.fuente
not(...)
lugar de0 if ... else 1
awk '${print $5}' ptpd_log_file | perl -ne '$_ > 0.000100 && print' > /tmp/outfile
. Pan comido. Cada idioma tiene su lugar.python -c "import sys; sys.exit(0 if float($num1) < float($num2) else 1)"
es simplementeawk "BEGIN{exit ($num1 > $num2 ? 0 : 1)}"
.Esta secuencia de comandos puede ayudar a comprobar si la
grails
versión instalada es mayor que la mínima requerida. Espero eso ayude.fuente
fuente
compruebe el código editado a continuación: -
Esto funciona bien.
fuente
Una solución que admite todas las notaciones posibles, incluida la notación científica con exponentes en mayúsculas y minúsculas (por ejemplo,
12.00e4
):fuente
Use korn shell, en bash puede que tenga que comparar la parte decimal por separado
fuente
Usando bashj ( https://sourceforge.net/projects/bashj/ ), un mutante bash con soporte java, solo escribe (y ES fácil de leer):
Por supuesto, la hibridación bashj bash / java ofrece mucho más ...
fuente
¿Qué tal esto? = D
fuente
exit 0
informar la verdad yexit 1
devolver falso; entonces puede simplificar a la notablemente eleganteif awk 'BEGIN { exit (ARGV[1] >= ARGV[2]) ? 0 : 1 }' "$VAL_TO_CHECK" 1; then
... (aún más elegante si encapsula el script Awk en una función de shell).