Estou tentando escrever um script no bash que verifique a validade de uma entrada do usuário.
Quero corresponder a entrada (digamos variável x
) a uma lista de valores válidos.
o que eu inventei no momento é:
for item in $list
do
if [ "$x" == "$item" ]; then
echo "In the list"
exit
fi
done
Minha pergunta é se existe uma maneira mais simples de fazer isso,
algo como um list.contains(x)
para a maioria das linguagens de programação.
Adição: a
lista de palavras é:
list="11 22 33"
meu código ecoará a mensagem apenas para esses valores, uma vez que list
é tratada como uma matriz e não como uma string, todas as manipulações de string serão validadas 1
enquanto eu gostaria que ela falhasse.
[[ $list =~ (^| )$x($| ) ]] && echo 'yes' || echo 'no'
x=.
contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.[[ " $list " =~ " $x " ]] && echo 'yes' || echo 'no'
. -lo do espaço assumindo correto é o separador e$x
não contém espaçoisIn()
para que você possa escrever o item primeiro nos parâmetros. Além disso, você podeecho
usar algo assim, em vez de usar oexit
seguinte:[[ $2 =~ (^|[[:space:]])$1($|[[:space:]]) ]] && echo 1 || echo 0
Para que você possa usar a função desta maneira:result=$(isIn "-t" "-o -t 45") && echo $result
Matvey está certo, mas você deve citar $ x e considerar qualquer tipo de "espaço" (por exemplo, nova linha) com
então, ie
fim então
ou
Observe que você deve usar
""
no caso de variáveis:fonte
$item
contenha caracteres especiais, como.
(mas a$list
variável provavelmente precisa ser citada dentro do teste). E a função pode ser definida ainda mais simples:contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.list="aa bb xx cc ff"
ex="aa bb"
$list =~ (^|[[:space:]])"$item"($|[[:space:]])
. Ou, se você tiver tempo, ficaria feliz em ouvir sua explicação para essa expressão. Nota: Eu acho que é uma expressão de expressão regular (começa com ^ etc), mas não sei o que = ~ significa. Então, eu adoraria uma explicação geral: PA solução mais fácil do IMHO é anexar e anexar a sequência original com um espaço e comparar com uma regex com
[[ ]]
isso não será falso positivo em valores com valores contendo a agulha como substring, por exemplo, com um palheiro
foo barbaz
.(O conceito é descaradamente roubado do JQuery's
hasClass()
-Method)fonte
haystack="foo:bar"
e[[ ":$haystack:" = *:$needle:* ]]
e quanto a
você pode verificar a saída ou a
$?
linha acima para tomar a decisão.grep -w
verifica padrões de palavras inteiras.fonte
Você também pode usar (* curingas) fora de uma declaração de caso, se usar colchetes duplos:
fonte
*My*
) devem estar no lado direito do teste.Se sua lista de valores deve ser codificada no script, é bastante simples testar usando
case
. Aqui está um pequeno exemplo, que você pode adaptar aos seus requisitos:Se a lista for uma variável de matriz em tempo de execução, uma das outras respostas provavelmente será um ajuste melhor.
fonte
Se a lista estiver corrigida no script, eu gosto do seguinte:
Em seguida, use
validate "$x"
para testar se$x
é permitido.Se você deseja uma linha única e não se importa com espaços em branco nos nomes dos itens, pode usar isso (observe em
-w
vez de-x
):Notas:
sh
com POSIX .validate
se não aceitar substrings (remover a-x
opção de grep se você quer isso).validate
interpreta seu argumento como uma sequência fixa, não como uma expressão regular (remova a-F
opção grep, se desejar).Código de exemplo para exercer a função:
fonte
Considere explorar as chaves de matrizes associativas . Eu presumo que isso supera a correspondência de regex / padrão e loop, embora eu não o tenha perfilado.
Resultado:
fonte
echo -n
) com uso criativo de parâmetros:do is="${list[$value]+is }"; echo "$value ${is:-is *not* }a member of ( ${!list[*]} )"; done
.Acho mais fácil usar o formulário
echo $LIST | xargs -n1 echo | grep $VALUE
conforme ilustrado abaixo:Isso funciona para uma lista separada por espaço, mas você pode adaptá-la a qualquer outro delimitador (como
:
) fazendo o seguinte:Observe que
"
são necessários para o teste funcionar.fonte
LIST="SOMEITEM1 ITEM2"
retornar true mesmo queITEM1
não está nelePensei em adicionar minha solução à lista.
fonte
Exemplos
na lista
fonte
Supondo que a variável TARGET possa ser apenas 'binomial' ou 'regressão', o seguinte seria:
Você pode adicionar mais strings à lista, separando-as com um | caractere (pipe).
A vantagem de usar o egrep é que você pode facilmente adicionar insensibilidade a maiúsculas e minúsculas (-i) ou verificar cenários mais complexos com uma expressão regular.
fonte
Esta é quase a sua proposta original, mas quase uma linha. Não é tão complicado quanto outras respostas válidas, e não depende das versões do bash (pode funcionar com os antigos).
Acho que minha proposta ainda pode ser melhorada, tanto em tamanho quanto em estilo.
fonte
Se não demorar muito; você pode apenas colocá-los entre igualdade ao longo de uma comparação lógica OU dessa forma.
Eu tive esse problema exato e, embora o exposto seja feio, é mais óbvio o que está acontecendo do que as outras soluções generalizadas.
fonte