A instrução Case permite apenas caracteres alfabéticos?

1
case "$1" in
all)
  echo "$1"
  ;;
[a-z][a-z][a-z][a-z][a-z][a-z])
  echo "$1"
  ;;
*)
  printf 'Invalid: %s\n' "$3"
  exit 1
  ;;
esac

Com isso, a única entrada aceita é tudo e 6 caracteres. Não aceita 4 caracteres ou mais que 6.

O que eu quero fazer aqui é permitir apenas caracteres, não dígitos ou símbolos, mas de duração ilimitada.

Qual é a sintaxe correta? Obrigado

    
por Freedo 19.01.2018 / 15:31

3 respostas

4

Você pode fazer isso com a correspondência de padrão padrão procurando por qualquer um dos caracteres não permitidos e rejeitando a entrada se encontrar algum. Ou você pode usar globs estendidos ( extglob ) ou regexes e explicitamente certificar-se de que a string inteira é composta por caracteres que são permitidos.

#/bin/bash
shopt -s extglob globasciiranges
case "$1" in *([a-zA-Z]))    echo "case ok" ;; esac
[[ "$1" = *([a-zA-Z]) ]]  && echo " [[  ok"
[[ "$1" =~ ^[a-zA-Z]*$ ]] && echo "rege ok"

globasciiranges impede que [a-z] corresponda às letras acentuadas, mas a correspondência regex não obedece a ela. Com a regex, você precisaria definir LC_COLLATE=C para impedir a correspondência.

Todos esses permitem a string vazia. Para evitar isso, altere os asteriscos para recompensas ( * to + ).

    
por 19.01.2018 / 16:09
7

dígitos ou símbolos são caracteres. Parece que você quer:

  1. apenas caracteres alfabéticos ( [[:alpha:]] )
  2. ou possivelmente caracteres alfabéticos, mas apenas no script latin (como seu a-z sugere)
  3. ou possivelmente caracter alfabético no roteiro latino e sem diacríticos.

A menos que a localidade seja C / POSIX, o que [a-z] corresponde é mais ou menos aleatório em bash (pelo menos em sistemas GNU).

Para 1, você deseja:

die() {
  printf >&2 '%s\n' "$1"
  exit 1
}
case $string in
  ("") die "Can't be empty";;
  (*[![:alpha:]]*) die "contains non-alphabetical characters";;
  (*) echo OK
esac

Isso aceitaria all , Stéphane (script latino), γράμμα (script grego), письмо (cirílico), mas não foo-bar , 123 ...

2 pode ser complicado, especialmente se você quiser considerar combinar diacríticos.

Para o 3, para ser executado em qualquer localidade, é necessário especificar os caracteres desejados:

ok=abcdefghijklmnopqstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

e na instrução case , use

(*[!$ok]*) die "contains characters not allowed";;

Ou você pode alternar para zsh , em que intervalos como [a-zA-Z] são baseados em pontos de código de caractere, portanto, inclua sempre abcdefghijklmnopqstuvwxyz ou com o bash 4.3 ou mais recente use o globasciirange opção para ter o mesmo comportamento em bash .

    
por 19.01.2018 / 15:48
0

Se você estiver usando bash ou equivalente, inclua na parte superior do seu script a linha set -s extglob para ativar globbing (uma forma de expressão regular) e, em seguida, na sua case statement, configure seu seletor como +([[:alpha:]]) , seguido, é claro, pelo ) exigido pela própria instrução case .

alpha é uma das várias classes de caracteres definidas nas páginas bash man. Ele engloba todos os caracteres alfabéticos, letras maiúsculas e minúsculas da sua localidade.

    
por 19.01.2018 / 19:48

Tags