1

I am a first year Computer technician student, and before now have never actually used linux. I grasped the basics of scripting fairly quickly and am trying to write a script that will create a directory and a soft link for each assignment. seeing as we average two assignments a week i thought this would be helpful.

I am having trouble making my script accept only numbers as variables. I have it mostly working (mostly) with use of 3 case statements, but would rather use basic regex with an if statement, if I can.

if [ $# != 1 ]; then

    red='\033[0;31m'
    NC='\033[0m'
    blue='\033[1;34m'
    NC='\033[0m'
    echo 1>&2 "${blue}ERROR:${NC} $0 :${red}expecting only one variable, you gave $#($*)${NC}"
    echo 1>&2 "${blue}Usage:${NC} $0 :${red}number of assignment.${NC}"
    exit 2

fi


case $1 in

    [[:punct:]]*) echo 1>&2 "Numeric Values Only"
    exit 2
    ;;
    [[:alpha:]]*) echo 1>&2 "Numeric Values Only"
    exit 2
    ;;
    [[:space:]]*) echo 1>&2 "Numeric Values Only"
    exit 2
    ;;
esac

the script then makes the directory and creates a soft link for the marking script (if its posted), and ends. can anyone help me shorten/eliminate the case statements

  • 1
    possible duplicate of [patterns in case statement in bash scripting](http://stackoverflow.com/questions/4554718/patterns-in-case-statement-in-bash-scripting) – lurker Mar 13 '15 at 19:07
  • Or see http://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash – ott-- Mar 13 '15 at 19:19

1 Answers1

1

You cannot use regular expressions in portable shell scripts (ones that will run on any POSIX compliant shell). In general, patterns in the shell are globs, not regular expressions.

That said, there are a few other options. If you are using Bash specifically, you have two choices; you can use extended globs, which give you some regex like functionality:

shopt -s extglob

case $1 in
    +([[:digit:]]) ) echo "digits" ;;
    *) echo "not digits" ;;
esac

Another option is that Bash has the =~ operator in the [[ ]] conditional construct to match strings against a regex; this doesn't work in a case statement, but works in an if:

if [[ $1 =~ [0-9]+ ]]
then
    echo "digits"
fi

Finally, if you want to do regular expression matching portably (so it will run in other POSIX shells like ash, dash, ksh, zsh, etc), you can call out to grep; if you pass -q, it will be silent about the matches but return success or failure depending on whether the input matched:

if echo "$1" | grep -qE "[0-9]+"
then
    echo "digits"
fi
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • all options produced more error messages, but with the use of a few more case statements the script is only accepting numeric values now. – Daniel Peregrym Mar 16 '15 at 18:58
  • @DanielPeregrym If you show the exact code that you used, and the exact error messages that you got (edit your question with the updated information), I can probably help you fix those errors. I tested every one of those examples before posting them, so I know that they work; I'd be interested to see why they aren't working for you. – Brian Campbell Mar 16 '15 at 20:45