scripts script programas pasar parametros operaciones manejo ejemplos comparar cadenas aritmeticas bash shell numeric

bash - programas - script linux ejemplos



Comparando nĂºmeros en Bash (7)

Estoy empezando a aprender cómo escribir guiones para el terminal bash, pero no puedo averiguar cómo hacer que las comparaciones funcionen correctamente. El script que estoy usando es:

echo "enter two numbers"; read a b; echo "a=$a"; echo "b=$b"; if [ $a /> $b ]; then echo "a is greater than b"; else echo "b is greater than a"; fi;

El problema que tengo es que compara el número a partir del primer dígito, es decir, 9 es mayor que 10000, pero 1 es mayor que 09

¿Cómo puedo convertir los números en un tipo para hacer una comparación verdadera?


En Bash, prefiero hacer esto, ya que se trata más como una operación condicional, a diferencia de usar (( )) que es más de aritmética.

[[ N -gt M ]]

A menos que haga cosas complejas como

(( (N + 1) > M ))

Pero cada uno tiene sus propias preferencias. Lo triste es que algunas personas imponen sus estándares no oficiales.

Actualizar:

En realidad, también puede hacer esto:

[[ ''N + 1'' -gt M ]]

Lo que le permite agregar algo más que podría hacer con [[ ]] además de elementos aritméticos.


En bash, debes hacer tu comprobación en el contexto aritmético :

if (( a > b )); then ... fi

Para shells POSIX que no admiten (()) , puede usar -lt y -gt .

if [ "$a" -gt "$b" ]; then ... fi

Puede obtener una lista completa de operadores de comparación con la help test .


Este código también puede comparar flotadores. Está utilizando awk (no es bash puro), sin embargo, esto no debería ser un problema, ya que awk es un comando POSIX estándar que probablemente se envía de forma predeterminada con su sistema operativo.

$ awk ''BEGIN {return_code=(-1.2345 == -1.2345) ? 0 : 1; exit} END {exit return_code}'' $ echo $? 0 $ awk ''BEGIN {return_code=(-1.2345 >= -1.2345) ? 0 : 1; exit} END {exit return_code}'' $ echo $? 0 $ awk ''BEGIN {return_code=(-1.2345 < -1.2345) ? 0 : 1; exit} END {exit return_code}'' $ echo $? 1 $ awk ''BEGIN {return_code=(-1.2345 < 2) ? 0 : 1; exit} END {exit return_code}'' $ echo $? 0 $ awk ''BEGIN {return_code=(-1.2345 > 2) ? 0 : 1; exit} END {exit return_code}'' $ echo $?

Para que sea más corto de usar, use esta función:

compare_nums() { # Function to compare two numbers (float or integers) by using awk. # The function will not print anything, but it will return 0 (if the comparison is true) or 1 # (if the comparison is false) exit codes, so it can be used directly in shell one liners. ############# ### Usage ### ### Note that you have to enclose the comparison operator in quotes. ############# # compare_nums 1 ">" 2 # returns false # compare_nums 1.23 "<=" 2 # returns true # compare_nums -1.238 "<=" -2 # returns false ############################################# num1=$1 op=$2 num2=$3 E_BADARGS=65 # Make sure that the provided numbers are actually numbers. if ! [[ $num1 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num1 is not a number"; return $E_BADARGS; fi if ! [[ $num2 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num2 is not a number"; return $E_BADARGS; fi # If you want to print the exit code as well (instead of only returning it), uncomment # the awk line below and comment the uncommented one which is two lines below. #awk ''BEGIN {print return_code=(''$num1'' ''$op'' ''$num2'') ? 0 : 1; exit} END {exit return_code}'' awk ''BEGIN {return_code=(''$num1'' ''$op'' ''$num2'') ? 0 : 1; exit} END {exit return_code}'' return_code=$? return $return_code } $ compare_nums -1.2345 ">=" -1.2345 && echo true || echo false true $ compare_nums -1.2345 ">=" 23 && echo true || echo false false


Resolví esto usando una pequeña función para convertir cadenas de versión a valores enteros simples que se pueden comparar:

function versionToInt() { local IFS=. parts=($1) let val=1000000*parts[0]+1000*parts[1]+parts[2] echo $val }

Esto hace dos suposiciones importantes:

  1. La entrada es una " cadena normal de SemVer "
  2. Cada parte está entre 0-999

Por ejemplo

versionToInt 12.34.56 # --> 12034056 versionToInt 1.2.3 # --> 1002003

Ejemplo de prueba para ver si el comando npm cumple con el requisito mínimo ...

NPM_ACTUAL=$(versionToInt $(npm --version)) # Capture npm version NPM_REQUIRED=$(versionToInt 4.3.0) # Desired version if [ $NPM_ACTUAL /< $NPM_REQUIRED ]; then echo "Please update to npm@latest" exit 1 fi


Sencillo y sencillo

#!/bin/bash a=2462620 b=2462620 if [ "$a" -eq "$b" ];then echo "They''re equal"; fi

Puede consultar esta hoja de trucos si desea más comparaciones de números en el maravilloso mundo de Bash Scripting.

En breve, los enteros solo se pueden comparar con:

-eq # equal -ne # not equal -lt # less than -le # less than or equal -gt # greater than -ge # greater than or equal


Si tiene flotadores, puede escribir una función y luego usarla, por ejemplo,

#!/bin/bash function float_gt() { perl -e "{if($1>$2){print 1} else {print 0}}" } x=3.14 y=5.20 if [ $(float_gt $x $y) == 1 ] ; then echo "do stuff with x" else echo "do stuff with y" fi


También hay una cosa buena que algunas personas pueden no saber:

echo $(( a < b ? a : b ))

Este código imprimirá el número más pequeño de a y b