GNU/Linux >> Znalost Linux >  >> Linux

Jak otestuji, zda je proměnná číslo v Bash?

Jedním z přístupů je použití regulárního výrazu, například takto:

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

Pokud hodnota není nutně celé číslo, zvažte vhodnou úpravu regulárního výrazu; například:

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

...nebo pro zpracování čísel se znaménkem:

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

Nikdo nenavrhl bashovu rozšířenou shodu vzorů:

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

nebo pomocí znakové třídy POSIX:

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

Následující řešení lze také použít v základních shellech, jako je Bourne, bez potřeby regulárních výrazů. V podstatě jakékoli operace vyhodnocení číselných hodnot, které nepoužívají čísla, povedou k chybě, která bude v shellu implicitně považována za nepravdivou:

"$var" -eq "$var"

jako v:

#!/bin/bash

var=a

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

Můžete také testovat za $? návratový kód operace, který je explicitnější:

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

Přesměrování standardní chyby slouží ke skrytí zprávy „očekávaný celočíselný výraz“, kterou bash vytiskne v případě, že nemáme číslo.

UPOZORNĚNÍ (díky komentářům níže):

  • Čísla s desetinnými tečkami nejsou identifikované jako platná „čísla“
  • Pomocí [[ ]] místo [ ] bude vždy vyhodnocena jako true
  • Většina shellů bez Bash vždy vyhodnotí tento výraz jako true
  • Chování v Bash je nezdokumentované, a proto se může bez varování změnit
  • Pokud hodnota obsahuje mezery za číslem (např. „1 a“), dojde k chybě, například bash: [[: 1 a: syntax error in expression (error token is "a")
  • Pokud je hodnota stejná jako var-name (např. i="i"), dojde k chybě, například bash: [[: i: expression recursion level exceeded (error token is "i")

Bez bashismů (funguje i v System V sh),

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

To odmítne prázdné řetězce a řetězce obsahující jiné než číslice a přijme vše ostatní.

Záporná čísla nebo čísla s plovoucí desetinnou čárkou vyžadují další práci. Cílem je vyloučit - / . v prvním „špatném“ vzoru a přidejte další „špatné“ vzory obsahující jejich nevhodné použití (?*-* / *.*.* )


Linux
  1. How To Echo A Bang!?

  2. Jak číst řetězec jako hexadecimální číslo v Bash?

  3. Jak zopakovat nový řádek ve skriptech Bash Shell

  1. Chtěl bych uložit všechny argumenty příkazového řádku do skriptu Bash do jedné proměnné

  2. Linux bash:Přiřazení více proměnných

  3. Jak mohu otestovat svůj Bash skript na starších verzích Bash?

  1. Jak mohu získat poslední číslo z řetězce v bash?

  2. Jak odstranit proměnnou pouze pro čtení v bash?

  3. Jak bash testuje „nepravdu“?