0

For some reason I'm not getting the higher number patterns to work in this script.

#!/bin/bash
#
# guess_my_number.bash - my favorite number

echo "Can you guess my favorite number???"

echo -e -n "\n\n\033[32m Pick a number between 0 and 100 > "
read num
case $num in

  [0-6] )               echo "You're close...but too low" ;;
  [8-14] )              echo "You're close...but too high" ;;
  [15-100] )            echo "You're nowhere near my favorite number...sorry, try again" ;;
  7 )                   echo "YOU GUESSED MY FAVORITE NUMBER!" ;;
  * )                   echo "You didn't pick a number between 1 and 100!" ;;

esac

If I change [8-14] to [8..14] I get the echo response if I type in 8 when running the script but any other number from 9-100 gives me the wildcard echo response. If it's [8-14] it gives me the wildcard response too. Like I said the [0-6] pattern gives it's echo statement and so does 7.

What is my problem here?

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • 2
    Possible duplicate of [Using Case for Range of Numbers in Bash](http://stackoverflow.com/questions/12614011/using-case-for-range-of-numbers-in-bash) – Benjamin W. Feb 07 '17 at 05:05
  • Possible duplicate of [Regular expressions in a Bash case statement](http://stackoverflow.com/questions/9631335/regular-expressions-in-a-bash-case-statement) – codeforester Feb 07 '17 at 05:08
  • hmm... thanx but i'm not sure if i understand those other questions. – user7526725 Feb 07 '17 at 05:56

3 Answers3

0

This works tho...

if [ "$num" = "7" ]; then
  echo -e "\n\n\033[33m YOU GUESSED MY FAVORITE NUMBER!\n\n"
else
  echo "That's not my number. HINT: Red XIII"
  while [ "$num" != "7" ]; do
    echo -e -n "\n\033[32m Pick again > "
    read num
      if [ "$num" = "7" ]; then
        echo -e "\n\n\033[33m YOU GUESSED MY FAVORITE NUMBER!\n\n"
      fi
  done
fi

Not quite what I was going for.

0
#!/bin/bash
#
# guess_my_number.bash - my favorite number

echo "Can you guess my favorite number???"

echo -e -n "\n\n\033[32m Pick a number between 0 and 100 > "
read num
case $num in

 [0-6] )               echo "You're close...but too low" ;;
 [8-9] )            echo "You're close...but too high" ;;
 1[0-4])             echo "You're close...but too high" ;;
 [1-9][0-9] )            echo "You're nowhere near my favorite number...sorry, try again" ;;
  7 )                   echo "YOU GUESSED MY FAVORITE NUMBER!" ;;
  * )                   echo "You didn't pick a number between 1 and 100!" ;;

esac
Anup
  • 19
  • 5
  • @user7526725 make sure in you code you must have in range only combination of single digit. Hope it helped you. – Anup Feb 07 '17 at 08:13
  • @user7526725 you can use "or" operator "|" to have two line [8-9] ) echo "You're close...but too high" ;; 1[0-4]) echo "You're close...but too high" ;; new format: [8-9]|1[0-4] ) echo "You're close...but too high" ;; – Anup Feb 07 '17 at 09:55
  • I see. I thought it might have had to do with going over 0-9. Thanx. – user7526725 Feb 07 '17 at 16:27
0

As advised in the other links, case can perform only pattern matching and not arithmetice expansion. This means that you can use a range in [0-6] which regex will match any single character in the range 0-6, but the range [8-14] is not a valid pattern.

If you insist on going with case then your example should be like this:

case $num in
  ([0-6])                 echo "You're close...but too low" ;;
  ([8-9]|1[0-4])          echo "You're close...but too high" ;;
  (1[5-9]|[2-9][0-9]|100) echo "You're nowhere near my favorite number...sorry, try again" ;;
  7 )                     echo "YOU GUESSED MY FAVORITE NUMBER!" ;;
  * )                     echo "You didn't pick a number between 1 and 100!" ;;
esac  

The pattern (1[5-9]|[2-9][0-9]|100) regex speaking means:

1[5-9] : 15-16-17-18-29
[2-9][0-9] : Each number of first [] with one number of second [] = range 20-99
100 : Literally 100
PS: The | is used as OR operator.

Due to this case behavior , for comparing numbers use of if-then-else is preferred:

if [ "$num" -ge 0 ] && [ "$num" -le 6 ]; then
  echo "...."
elif [ "$num" -ge 8 ] &&  [ "$num" -le 14 ]; then
  echo "...."
elif [ "$num" -ge 15 ] &&  [ "$num" -le 100 ]; then
  echo "...."
elif [ "$num" -eq 7 ] 
  echo "...."
else
  echo "You didn't pick a number between 1 and 100!"
fi
George Vasiliou
  • 6,130
  • 2
  • 20
  • 27