1

Here I found nice solution to test if variable is a number:

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

I'm trying to modify it to test if variable is a 1,2,3 or 4-digit natural number (within a range 0-9999), so I added |*[0-9]{5,}* to exclude numbers with more than 5 digits, but the code below prints good for numbers greater then 9999 e.g. 1234567.

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

I'm using ash from busybox.

Radek Daniluk
  • 405
  • 6
  • 14
  • I mixed up **regular expressions** with **shell patterns**. According to ash man documentation: _A pattern consists of normal characters, which match themselves, and meta-characters. The meta-characters are “!”, “*”, “?”, and “[”. These characters lose their special meanings if they are quoted._ So `{5,}*` is not recognized. – Radek Daniluk Aug 06 '17 at 13:18

3 Answers3

1

You can use numeric testing:

$ s=123
$ (( s>=0 && s<=9999 )) && echo "true" || echo "false"
true
$ s=123456
$ (( s>=0 && s<=9999 )) && echo "true" || echo "false"
false
$ s=-1
$ (( s>=0 && s<=9999 )) && echo "true" || echo "false"
false

You just need to make sure that the string is all digits with optional ± at the start. A non numeric string used in numeric context will evaluate to 0 so you need to test for that.

Which you can use your case statement for:

case $s in 
  ''|*[!0-9]*) echo bad ;;
  *) (( s>=0 && s<=9999 )) && echo "true" || echo "false" ;;
esac

Or:

$ [ "$s" -eq "$s" ] 2>/dev/null && (( s>=0 && s<=9999 )) && echo "true" || echo "false"

Works too.

These should work under any POSIX shell.

dawg
  • 98,345
  • 23
  • 131
  • 206
0

Not sure if you need this in a case statement, since I would just do:

if { test "$string" -ge 0 && test "$string" -lt 10000; } 2> /dev/null; then
  echo good
else 
  echo bad
fi

If you want to use a case statement in a strictly portable shell, you're probably stuck with:

case $string in 
    [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]) echo good;;
     *) echo bad;;
esac
William Pursell
  • 204,365
  • 48
  • 270
  • 300
0
case  $([[ $num =~ ^[0-9]+$ ]] && echo 0) in
 0) echo good ;;
*) echo bad ;;
esac
Sam
  • 404
  • 4
  • 7