Una risposta chiara è già stata data da @charles Dufy e altri. Una soluzione bash pura sarebbe usare il seguente:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
Sebbene per i numeri reali non sia obbligatorio disporre di un numero prima del punto di radice .
Per fornire un supporto più completo ai numeri fluttuanti e alla notazione scientifica (molti programmi in C / Fortran o altrimenti esporteranno il float in questo modo), un'utile aggiunta a questa riga sarebbe la seguente:
string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
In questo modo si ottiene un modo per differenziare i tipi di numero, se si sta cercando un tipo specifico:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
echo $string is an integer
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
echo $string is a float
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
echo $string is a scientific number
else
echo $string is not a number
fi
Nota: potremmo elencare i requisiti sintattici per la notazione decimale e scientifica, uno è quello di consentire la virgola come punto radicale, così come ".". Vorremmo quindi affermare che ci deve essere solo uno di questi punti radicali. Ci possono essere due segni +/- in un float [Ee]. Ho imparato alcune altre regole dal lavoro di Aulu e ho testato contro stringhe errate come '' '-' '-E-1' '0-0'. Ecco i miei strumenti regex / substring / expr che sembrano reggere:
parse_num() {
local r=`expr "$1" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'`
nat='^[+-]?[0-9]+[.,]?$' \
dot="${1%[.,]*}${r}${1##*[.,]}" \
float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
[[ "$1" == $dot ]] && [[ "$1" =~ $float ]] || [[ "$1" =~ $nat ]]
} # usage: parse_num -123.456
test && echo "foo" && exit 0 || echo "bar" && exit 1
approccio che stai usando potrebbe avere degli effetti collaterali non intenzionali, se l'eco fallisce (forse l'output è verso un FD chiuso),exit 0
verrà saltato e il codice proverà a farloecho "bar"
. Se fallisce anche in questo, la&&
condizione fallirà e non verrà nemmeno eseguitaexit 1
! L'uso diif
istruzioni effettive piuttosto che&&
/||
è meno soggetto a effetti collaterali imprevisti.