case
é apenas para correspondência de padrões, não fará avaliação aritmética (exceto, talvez, se você considerar zsh
o <x-y>
operador de correspondência de padrões estendida). O [...]
é apenas para corresponder a um caractere (ou elemento de intercalação em algumas implementações) com base no conjunto especificado em. Assim, por exemplo [0-80]
iria corresponder um personagem, se ele é um dos 0
que 8
ou 0
(isto é, de 0, 1, 2, 3, 4, 5, 6, 7, 8).
Você pode combinar números com padrões como:
case $(($number)) in
([0-9]|[1-7][0-9]|80) echo ">=0<=80";;
(8[1-9]|9[0-9]|100) echo ">=81<=100";;
... and so on
esac
Mas você pode ver facilmente que não é a ferramenta certa.
Ele [...]
corresponde a um caractere em relação à lista de caracteres especificados, portanto [121-300]
corresponde a qualquer caractere que seja 1, 2, 1 a 3, 0 ou 0, portanto é o mesmo que [0-3]
ou [0123]
.
Usar:
if [ "$number" -ge 0 ] && [ "$number" -le 80 ]; then
echo ">=0<=80"
elif [ "$number" -ge 81 ] && [ "$number" -le 100 ]; then
echo ">=81<=100"
elif ... and so on
...
fi
Outra maneira de usar case
seria como:
case $((
(number >= 0 && number <= 80) * 1 +
(number > 80 && number <= 100) * 2 +
(number > 100 && number <= 120) * 3 +
(number > 120 && number <= 300) * 4)) in
(1) echo ">=0<=80";;
(2) echo ">=81<=100";;
(3) echo ">=101<=120";;
(4) echo ">=121<=300";;
(0) echo "None of the above";;
esac
Ou use o operador ternário ( x ? y : z
):
case $((
number >= 0 && number <= 80 ? 1 :
number > 80 && number <= 100 ? 2 :
number > 100 && number <= 120 ? 3 :
number > 120 && number <= 300 ? 4 : 0)) in...
Ou como @mikeserv, pense fora da caixa, inverta a case
lógica e combine 1
com o valor dessas comparações aritméticas .
if [ n < 0 ] - elif [ n <= 80 ] - elif [ n <= 100 ] ... - else
. Menos digitação, menos propenso a erros.Na verdade, isso é realmente fácil de fazer. A questão
case
é que ele sempre será expandido apenas o necessário para encontrar a primeira correspondência contra um padrão. Esse é o comportamento especificado. E assim você pode configurá-lo com uma string conhecida e avaliar as expansões dos padrões.case
nunca expandirá mais desses padrões do que o necessário para encontrar um 1 inicial no padrão. Isso é especialmente importante ao trabalhar com a entrada do usuário, porque significa que você pode verificar com segurança o conteúdo de$number
antes de tentar colocá-lo em um contexto de expansão aritmética na mesma instrução de caso em que você realmente o coloca em uma expansão matemática.fonte
case
. existem algumas coisas legais que você pode fazer com$((
matemática))
ecase
- especialmente tarefas circunvizinhas em padrões que nunca acontecem até que precisem - e você pode até criar árvores de análise que expandem recursões aninhadas se você preencher os padrões com umaalias
cadeia. é a maneira mais rápida encontrada para obter um shell para fazer coisas como tradução de caracteres e trocar caracteres por valores de bytes. pode ser bem rápido - o pior caso C-Locale ASCII + <> octal é 7 expansões básicas de padrão POSIX.Isso não é muito bom, mas você pode usar isso:
fonte