Teste para qualquer família de valores relacionados em uma variável Bash [closed]

1

Desculpas se isto foi respondido anteriormente, mas não consegui encontrar muita coisa online.

Veja o que estou tentando realizar:

if [[ "${hostname}" = (foo | bar)servername(01 | 02 | 03) ]]; then
  var="foobarfoo"
fi

Com isso, qualquer um dos itens a seguir atenderia aos critérios: fooservername01, barservername02, fooservername03, barservername03, etc.

Eu consegui isso de uma forma muito mais ineficiente:

if [[ ${hostname} == "fooservername01" ]] || [[ ${hostname} == "fooservername02" ]] || [[ ${hostname} == "fooservername03" ]] || [[ ${hostname} == "barservername01" ]] || [[ ${hostname} == "barservername02" ]] || [[ ${hostname} == "barservername03" ]]; then
  var="foobarfoo"
fi

Mas estou procurando otimizar / simplificar o código.

Qualquer insight seria apreciado, pois ainda sou muito novo em bash scripting e scripts em geral.

    
por Tronyx 13.01.2016 / 09:55

4 respostas

2

Você pode fazer isso quase exatamente como você o escreveu. Quando você estiver usando [[ , então == usa correspondência de padrões no lado direito. Em um padrão de Bash, você pode combinar um de uma seleção de padrões usando @(a|b|c) :

if [[ "${hostname}" = @(foo|bar)servername@(01|02|03) ]]; then

Isso corresponde a cada um dos casos que você identifica. @( ... | ... ) corresponde a qualquer um dos padrões separados por | . Você também pode usar outros globs * e ? , [character classes] e outros padrões compostos para padrões repetidos, opcionais ou negados.

O uso desses padrões estendidos precisa da opção extglob shell ativada. Se ainda não estiver (você receberá um erro de sintaxe), poderá ativá-lo com:

shopt -s extglob

em qualquer lugar antes que seu if apareça.

Se você preferir e estiver mais familiarizado com eles, também poderá usar horários regulares estendidos expressões usando o operador =~ no lugar de == .

    
por 13.01.2016 / 10:05
1
case ${hostname%"servername0"[123]} in
("$hostname") ! :;; 
(foo|bar) ;;
(*) ! :;; esac
    
por 13.01.2016 / 10:28
0

Acho que você deveria usar grep para isso. Por exemplo:

HOST_REGEX='(foo|bar)servername(01|02|03)'

if grep -qE "${HOST_REGEX}" <<< "${hostname}"
then
  var="foobarfoo"
fi

Em uma linha:

grep -qE '(foo|bar)servername(01|02|03)' <<< "${hostname}" && var="foobarfoo"
    
por 13.01.2016 / 10:03
0

Você pode usar o operador =~ test. Isso aceita expressões regulares estendidas (sem aspas) (semelhante a egrep ).

if [[ "$hostname" =~ (foo|bar)servername(01|02|03) ]]
then echo matches
else echo no match
fi
    
por 13.01.2016 / 10:10