Às vezes, uma construção diferente pode ficar mais legível:
case $num in
9|75|200) echo "do this" ;;
40|53|63) echo "do something for this" ;;
*) echo "for other do this" ;;
esac
#!/bin/sh
if [ $num -eq 9 -o $num -eq 75 -o $num -eq 200 ]; then
echo "do this"
elif [ $num -eq 40 -o $num -eq 53 -o $num -eq 63]; then
echo "do something for this"
else
echo "for other do this"
fi
Existe outra maneira de reduzir a expressão na instrução if
?
Talvez algo como
[ $num -eq (9,75,200) ]
BTW, eu não tenho utilitários GNU neste SO.
cuidadoso, o posix não define teste com mais de 4 argumentos, então sua construção de teste é indefinida . veja a 6ª armadilha do bash
Então você precisaria, se usar teste, para ser mais detalhado:
if [ "$arg" = 9 ] || [ "$arg" = 75 ] || [ "$arg" = 200 ]
ou use caso em vez
case "$arg" in
9|75|200) do something ; ;
40|53|63) do that ;;
*) else ... ;;
esac
Parece um trabalho para uma função:
test_num() {
n=$1; shift
for arg do
[ "$arg" -eq "$n" ] && return 0
done
} 2>/dev/null
if test_num "$num" 9 75 200; then
echo "do this"
elif test_num "$num" 40 53 63; then
echo "do something for this"
else
echo "for other do this"
fi
Se você estiver usando bash
ou ksh
ou zsh
(e talvez alguns outros, não me lembro agora), você pode usar [[ ... ]]
em vez de [ ... ]
, o que permite que você faça a expressão regular corresponde em sh.
por exemplo,
if [[ "$num" =~ ^(9|75|200)$ ]] ; then
echo "do this"
elif [[ "$num" =~ ^(40|53|63)$ ]] ; then
echo "do something for this"
else
echo "for other do this"
fi
OBSERVAÇÃO: como você deseja uma correspondência exata nos números específicos, é importante que o regex esteja ancorado nas duas extremidades com ^
e $
, caso contrário, eles corresponderão a outros números que os contêm (por exemplo, '99' ou '7500' ou '163')
Uma solução POSIX alternativa:
if printf '%s' "$num" | grep -xE '(9|75|200)' >/dev/null; then
echo "do this"
elif printf '%s' "$num" | grep -xE '(40|53|63)' >/dev/null; then
echo "do something for this"
else
echo "for other do this"
fi
Isso é muito lento ~ 50 vezes mais lento que a opção case
.
Este é um menor e acredito que um script mais simples, apenas duas vezes o tempo da opção de caso:
#!/bin/sh
num="$1" a='9 75 200' b='40 53 63'
tnum() {
for arg
do [ "$arg" = "$num" ] && return 0
done return 1
}
if tnum $a; then
echo "do this"
elif tnum $b; then
echo "do something for this"
else
echo "for other do this"
fi
CAVEAT: Nenhum teste [ "$arg" = "$num" ]
funcionará em todos os casos, isso falha em 00 = 0
, por exemplo.
E um teste numérico [ "$arg" -eq "$num" ]
não corresponderá aos valores vazios [ "" -eq "" ]
.
Você pode escolher o que funciona melhor no seu caso.
Tags shell scripting shell-script