Matching numbers with glob pattern

I am trying to match using a glob pattern. However, this match is failing:

dgt='^+([0123456789])$'
[[ "$1" == $dgt  ]] && echo "SUCCESS" || echo "FAILURE"
Asked By: Vera

||

If glob pattern matching is not absolutely required, you can alternatively use regular expressions instead.

With Bash you can use the =~ regex operator:

dgt='^[[:digit:]]+$'
[[ "$1" =~ $dgt ]] && echo "SUCCESS" || echo "FAILURE"
Answered By: Stephan

Your pattern, ^+([0123456789])$, is a mix of an extended globbing pattern and a regular expression. A globbing pattern does not need to be anchored explicitly, as it is always anchored anyway. Therefore, a globbing pattern starting with ^ and ending with $ would match those literal characters at the start and end of a string. If you want to use a globbing pattern and don’t want to match ^ at the start and $ at the end, remove these.

You will end up with the following code:

#!/bin/bash

# Bash releases earlier than 4.1 needs to enable the extglob shell
# option.  For release 4.1+, the pattern used in [[ ]] is assumed
# to be an extended globbing pattern.
#
# shopt -s extglob

pattern='+([0123456789])'

if [[ $1 == $pattern ]]; then
   echo 'contains only digits'
else
   echo 'contains non-digit or is empty'
fi

In a shell with no extended globbing patterns, it’s easier to match non-digits:

#!/bin/sh

case $1 in
    *[!0123456789]*)
        echo 'contains non-digit' ;;
    '')
        echo 'is empty' ;;
    *)
        echo 'contains only digits'
esac

In the bash shell, you can use the above code too, as it portable and would work in all sh-compatible shells, or you could use

#!/bin/bash

pattern='*[!0123456789]*'

if [[ $1 == $pattern ]]; then
   echo 'contains non-digit'
elif [ -z "$1" ]; then
   echo 'is empty'
else
   echo 'contains only digits'
fi
Answered By: Kusalananda on strike
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.