GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo pruebo si una variable es un número en Bash?

Un enfoque es usar una expresión regular, así:

re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
   echo "error: Not a number" >&2; exit 1
fi

Si el valor no es necesariamente un número entero, considere modificar la expresión regular de manera adecuada; por ejemplo:

^[0-9]+([.][0-9]+)?$

...o, para manejar números con un signo:

^[+-]?[0-9]+([.][0-9]+)?$

Nadie sugirió la coincidencia de patrones extendida de bash:

[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"

o usando una clase de carácter POSIX:

[[ $1 == ?(-)+([[:digit:]]) ]] && echo "$1 is an integer"

La siguiente solución también se puede usar en shells básicos como Bourne sin necesidad de expresiones regulares. Básicamente, cualquier operación de evaluación de valores numéricos que no utilice números dará como resultado un error que se considerará implícitamente como falso en el shell:

"$var" -eq "$var"

como en:

#!/bin/bash

var=a

if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
  echo number
else
  echo not a number
fi

¿También puedes probar por $? el código de retorno de la operación que es más explícito:

[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
   echo $var is not number
fi

La redirección del error estándar está ahí para ocultar el mensaje de "expresión entera esperada" que bash imprime en caso de que no tengamos un número.

ADVERTENCIAS (gracias a los comentarios a continuación):

  • Los números con puntos decimales no identificado como "números" válidos
  • Usando [[ ]] en lugar de [ ] siempre evaluará a true
  • La mayoría de los shells que no son Bash siempre evaluarán esta expresión como true
  • El comportamiento en Bash no está documentado y, por lo tanto, puede cambiar sin previo aviso
  • Si el valor incluye espacios después del número (por ejemplo, "1 a") produce un error, como bash: [[: 1 a: syntax error in expression (error token is "a")
  • Si el valor es el mismo que var-name (por ejemplo, i="i"), produce un error, como bash: [[: i: expression recursion level exceeded (error token is "i")

Sin bashisms (funciona incluso en System V sh),

case $string in
    ''|*[!0-9]*) echo bad ;;
    *) echo good ;;
esac

Esto rechaza cadenas vacías y cadenas que no contienen dígitos, aceptando todo lo demás.

Los números negativos o de coma flotante necesitan un trabajo adicional. Una idea es excluir - / . en el primer patrón "malo" y agregue más patrones "malos" que contengan usos inapropiados de ellos (?*-* / *.*.* )


Linux
  1. ¿Cómo leer una cadena como número hexadecimal en Bash?

  2. Cómo hacer eco de una nueva línea en Bash Shell Scripts

  3. Me gustaría almacenar todos los argumentos de la línea de comandos en un script Bash en una sola variable

  4. Linux bash:Asignación de múltiples variables

  5. BASH:cómo realizar operaciones aritméticas con números en una tubería

Cómo verificar si existe un archivo o directorio en Bash

Variable de exportación de bash

Bash printf - Cómo imprimir una variable en Bash

Cómo usar operadores de prueba de archivos Bash en Linux

Cómo usar el comando echo en Bash Scripts en Linux

Cómo establecer la variable de entorno en Bash