Adicione um caso padrão:
case $price in
[0-9] | "." | "$") true
;;
*)
do-something
;;
esac
Como eu adiciono a condição no caso em que se não detectar as condições necessárias, ele irá executar o comando.
Meu código:
case $price in
[0-9] | "." | "$") echo "Numbers, . , $ Only"
;;
esac
Este comando será executado se detectar números, "." e "$". Como mudá-lo em um sentido, se não detectá-los, o comando será executado. Ou existem outros comandos melhores para usar para fazer essa função.
Esta resposta não se refere ao problema case
já explicado, mas ao problema de correspondência.
Primeiramente, precisamos de uma definição de como as strings válidas podem parecer. A definição mais fácil permitiria, claro, apenas uma estrutura como
00
) Como uma expressão regular (por exemplo, grep
, consulte man 7 regex
), isso seria escrito como:
^[0-9]+\.[0-9][0-9]\$$
^
marca o início da string, ou seja, não pode haver nada antes do [0-9]+
\.
para ser tratado como ponto literal \$
para ser tratado como literal $
marca o final da string, ou seja, não pode haver nada após o literal $
Teste:
> echo '0123.45$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
0123.45$
Se a definição for alterada para que tanto o ponto com os dígitos finais quanto o sinal de dólar sejam opcionais, a regex mudará para
^[0-9]+(\.[0-9][0-9])?\$?$
Teste:
> echo '0123$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
# no match
> echo '0123$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123$
> echo '0123.45$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123.45$
O shell pode trabalhar com expressões regulares diretamente, mas não dentro de padrões case
. Você precisa da estrutura [[ ]]
. Mas como você quer saber apenas se uma string corresponde ou não, não há razão para usar case
:
if [[ "$price" =~ ^[0-9]+(\.[0-9][0-9])?\$?$ ]]; then
:
else
:
fi
Se você realmente precisar de case
, então você pode definir a opção extglob
com o shell bulitin shopt
e reescrever o regex para um "shell regex":
shopt -s extglob
^[0-9]+(\.[0-9][0-9])?\$?$
torna-se então
+([0-9])?(.[0-9][0-9])?($)
levando $
Se você quiser $0123.45
em vez de 0123.45$
, então obviamente terá que colocar o cheque de $
no início:
grep
/ [[ ]]
: ^\$?[0-9]+(\.[0-9][0-9])?$
?($)+([0-9])?(.[0-9][0-9])
verificação mais fácil
Se você não se importa com o pedido, mas com os caracteres certos, pode usar expressões muito mais fáceis:
grep
/ [[ ]]
: ^[0-9.$]+$
+([0-9.$])
exemplo
#! /bin/bash
shopt -s extglob
for value in 1234 1234EUR; do
case "$value" in
+([0-9]))
echo "value OK: '${value}'"
;;
*)
echo "value not OK: '${value}'"
;;
esac
done
Para corresponder uma string contendo apenas um único inteiro positivo com uma instrução shell case
, você pode fazer:
case "${string:--}" in
(*[!0-9]*)
! echo 'Invalid value for $string!';;
(*[!0]*)
echo "$string is a positive integer greater than 0.";;
(*)
echo "$string is 0.";;
esac
Na primeira correspondência de case
, faço a triagem de qualquer valor da expansão ${string:--}
que contenha até mesmo um único caractere que não esteja entre 0123456789
. No caso de $string
não ser definido ou nulo, ele será expandido para -
e, assim, ainda corresponderá a esse padrão. O retorno inicial !
inverte echo
(que é sempre 0) para um 1 - e assim a construção case
retorna 1 se $string
contiver um valor inválido.
No próximo eu igualo qualquer valor para $string
contendo um único dígito que não seja 0 - e, portanto, qualquer número de 0s iniciais em qualquer valor válido para $string
corresponderá como um número positivo.
O último corresponde a qualquer que não corresponda aos dois anteriores - o que quer dizer que corresponde apenas a um ou mais 0s.