Como negar um padrão de caso

2

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.

    
por Zac 13.01.2015 / 06:18

3 respostas

4

Adicione um caso padrão:

case $price in
[0-9] | "." | "$") true
            ;;
*) 
   do-something
   ;;
esac
    
por 13.01.2015 / 06:40
2

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

  1. comece com um ou mais dígitos (zeros à esquerda permitidos)
  2. ponto decimal
  3. dois dígitos finais (se necessário 00 )
  4. Cifrão (sem espaço à esquerda)

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]+
  • O ponto é de escape \. para ser tratado como ponto literal
  • O sinal de dólar tem o escape \$ para ser tratado como literal
  • o trailing $ 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])?$
  • correspondência de padrões de shell: ?($)+([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.$]+$
  • correspondência de padrões de shell: +([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
    
por 13.01.2015 / 19:24
1

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.

    
por 18.01.2015 / 22:58

Tags