GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso verificare se una variabile è un numero in Bash?

Un approccio consiste nell'utilizzare un'espressione regolare, in questo modo:

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

Se il valore non è necessariamente un numero intero, valuta la possibilità di modificare la regex in modo appropriato; ad esempio:

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

...oppure, per gestire i numeri con un segno:

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

Nessuno ha suggerito il pattern matching esteso di bash:

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

o utilizzando una classe di caratteri POSIX:

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

La seguente soluzione può essere utilizzata anche in shell di base come Bourne senza la necessità di espressioni regolari. Fondamentalmente qualsiasi operazione di valutazione del valore numerico che utilizza non numeri risulterà in un errore che sarà implicitamente considerato falso nella shell:

"$var" -eq "$var"

come in:

#!/bin/bash

var=a

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

Puoi anche provare per $? il codice di ritorno dell'operazione che è più esplicito:

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

Il reindirizzamento dell'errore standard è lì per nascondere il messaggio "espressione intera attesa" che bash stampa nel caso in cui non abbiamo un numero.

AVVERTIMENTI (grazie ai commenti qui sotto):

  • I numeri con punti decimali non identificati come "numeri" validi
  • Usando [[ ]] invece di [ ] restituirà sempre true
  • La maggior parte delle shell non Bash valuterà sempre questa espressione come true
  • Il comportamento in Bash non è documentato e potrebbe quindi cambiare senza preavviso
  • Se il valore include spazi dopo il numero (ad es. "1 a") produce un errore, come bash: [[: 1 a: syntax error in expression (error token is "a")
  • Se il valore è lo stesso di var-name (ad es. i="i"), produce un errore, come bash: [[: i: expression recursion level exceeded (error token is "i")

Senza bashismi (funziona anche nel System V sh),

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

Questo rifiuta le stringhe vuote e le stringhe che non contengono cifre, accettando tutto il resto.

I numeri negativi o in virgola mobile richiedono un lavoro aggiuntivo. Un'idea è quella di escludere - / . nel primo pattern "cattivo" e aggiungi altri pattern "cattivi" che ne contengono gli usi inappropriati (?*-* / *.*.* )


Linux
  1. Script Bash(I)

  2. Come fare eco a un botto!?

  3. Come leggere la stringa come numero esadecimale in Bash?

  4. Come fare eco a una nuova riga negli script di Bash Shell

  5. Vorrei memorizzare tutti gli argomenti della riga di comando in uno script Bash in una singola variabile

Come verificare se esiste un file o una directory in Bash

Variabile di esportazione Bash

Bash printf - Come stampare una variabile in Bash

Come utilizzare gli operatori di test di file Bash in Linux

Come utilizzare il comando echo negli script Bash in Linux

Come impostare la variabile d'ambiente in Bash