一致のためにグローバルパターンを使用しようとしています。しかし、このゲームは失敗します:
dgt='^+([0123456789])$'
[[ "$1" == $dgt ]] && echo "SUCCESS" || echo "FAILURE"
答え1
パターンは、^+([0123456789])$
拡張されたワイルドカードパターンと正規表現の混合です。ワイルドカードパターンは常に固定されているため、明示的な固定は必要ありません。したがって、^
開始および終了するワイルドカードパターンは、$
文字列の先頭と末尾のリテラル文字と一致します。ワイルドカードパターンを使用して^
開始と終了が一致しないようにするには、$
そのパターンを削除します。
次のコードで終わります。
#!/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
拡張されたワイルドカードパターンを持たないシェルでは、数値以外の項目を一致させる方が簡単です。
#!/bin/sh
case $1 in
*[!0123456789]*)
echo 'contains non-digit' ;;
'')
echo 'is empty' ;;
*)
echo 'contains only digits'
esac
シェルでは、bash
上記のコードは移植可能で互換性のあるsh
すべてのシェルで動作するため、使用することもできます。
#!/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
答え2
グローバルパターンマッチングが必ずしも必要でない場合は、正規表現を使用することもできます。
=~
Bashでは正規表現演算子を使用できます。
dgt='^[[:digit:]]+$'
[[ "$1" =~ $dgt ]] && echo "SUCCESS" || echo "FAILURE"