Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I match a numeric string in a bash case statement

Tags:

bash

case

numeric

I'm trying to match a string of 5 to 7 numbers in a case statement. Nothing I've tried successfully works. This is one of the things I tried.

^[0-9]*$ ) 
  echo "Got it!" 
  ;;

How do I do this successfully?

like image 711
Josiah Avatar asked Jun 02 '26 22:06

Josiah


2 Answers

The patterns in a bash case statement are file globs, not regular expressions. Your best option may be an if/else chain instead of case:

if [[ "$string" =~ ^[0-9]{5,7}$ ]]; then
  echo "Got it!"
fi

However, if you are less picky about the exact length, you can use the extended glob feature to match "1 or more digits":

shopt -s extglob
case "$string" in
  (+([0-9])) echo "Got it!";;
esac
like image 73
Mark Reed Avatar answered Jun 05 '26 01:06

Mark Reed


$ shopt -s extglob
$ isNum() { case $1 in (+([0-9])) echo 'Got it!' ;; esac; }
$ isNum 123A
$ isNum A123
$ isNum 1234
Got it!

If you want to also check length, that might be done separately:

isNum() {
  local len=${#1}
  if (( len < 5 || len > 7 )); then return; fi
  case $1 in (+([0-9])) echo 'Got it!' ;; esac
}

The trick here is "extglob" (extended glob) syntax, which allows functionality similar to proper regular expressions. +(...) in an extglob means "1 or more of ...".

See the bash-hackers page Patterns and pattern matching for details.

Except in ksh93, globs are not powerful enough to match a specific number of repetitions -- you need to actually write that out yourself. For instance:

# this is very clumsy, but works in all POSIX shells
isNum() {
  case $1 in [0-9][0-9][0-9][0-9][0-9])           : "Matched 5" ;;
             [0-9][0-9][0-9][0-9][0-9][0-9])      : "Matched 6" ;;
             [0-9][0-9][0-9][0-9][0-9][0-9][0-9]) : "Matched 7" ;;
             *) return ;;
  esac
  echo "Got it!" # only reached if the "return" didn't happen
}

Thus, you're probably better off using the bash-only regex syntax described in the answer by Mark Reed -- see also the relevant bash-hackers page.

like image 23
Charles Duffy Avatar answered Jun 05 '26 01:06

Charles Duffy