case $cmils in
3[2-9][0-9]|40[0-3])
cawg="25 AWG"
;;
40[4-9]|4[1-9][0-9]|50[0-9])
cawg="24 AWG"
;;
51[0-9]|6[0-3][0-9]|64[01])
cawg="23 AWG"
;;
Estou construindo uma função que calculará a bitola do fio necessária, dada a amperagem, a distância (em pés) e a queda de tensão permitida.
Posso calcular os "mils circulares" dados esses valores e, com isso, obter o AWG exigência . Comecei a criar uma declaração if
elif
grande para comparar os mils circulares com o indicador respeitado, mas acredito que case
é a ferramenta certa para isso.
Ainda não encontrei exemplos de casos usados para comparar números, por isso estou pensando se é possível fazer algo como abaixo:
what.gauge () {
let cmils=11*2*$1*$2/$3
let amils=17*2*$1*$2/$3
case $cmils in
320-403)
cawg="25 AWG"
;;
404-509)
cawg="24 AWG"
;;
510-641)
cawg="23 AWG"
;;
etc...
}
Como você está procurando testes aritméticos e o caso não faz aritmética, if-then
parece a abordagem natural:
if [ "$cmils" -lt 320 ]
then
cawg="??"
elif [ "$cmils" -le 403 ]
then
cawg="25 AWG"
elif [ "$cmils" -le 509 ]
then
cawg="24 AWG"
elif [ "$cmils" -le 641 ]
then
cawg="23 AWG"
fi
Eu prefiro soluções portáteis, mas algumas pessoas são apaixonadas pela sintaxe aritmética do bash:
if ((cmils < 320))
then
cawg="??"
elif ((cmils <= 403))
then
cawg="25 AWG"
elif ((cmils <= 509))
then
cawg="24 AWG"
elif ((cmils <= 641))
then
cawg="23 AWG"
fi
Isso é mais poderoso e mais frágil do que a sintaxe POSIX. Para ver o porquê, experimente este código depois de definir cmils=cmils
.
Como outros já disseram, case
não suporta operadores de comparação, apenas glob matching de padrões.
No entanto, você pode fazer um conjunto de if / elif / fi declarações parecer mais como uma declaração de caso formatando-a de forma diferente. por exemplo, com base na resposta de John1024:
if [ "$cmils" -lt 320 ]; then cawg='??'
elif [ "$cmils" -le 403 ]; then cawg='25 AWG'
elif [ "$cmils" -le 509 ]; then cawg='24 AWG'
elif [ "$cmils" -le 641 ]; then cawg='23 AWG'
fi
ou até mesmo:
[ "$cmils" -ge 320 ] && [ "$cmills" -le 403 ] && cawg='25 AWG'
[ "$cmils" -ge 404 ] && [ "$cmills" -le 509 ] && cawg='24 AWG'
[ "$cmils" -ge 510 ] && [ "$cmills" -le 641 ] && cawg='23 AWG'
NOTA: ao contrário de qualquer coisa usando elif
, essa variante tem a desvantagem de executar pelo menos o primeiro teste de cada uma dessas linhas. Usar elif
irá ignorar todos os testes restantes depois que qualquer teste for avaliado como verdadeiro. Você poderia colocar algo assim em uma função e adicionar && return
após configurar cawg
.
Pessoalmente, acho que qualquer uma delas é muito mais legível (sem todos os feedfeeds extras e recuo alternado que bagunça as coisas), mas as opiniões variam muito sobre essa questão específica de estilo de codificação / indentação:)
Com tudo alinhado nas mesmas colunas (ou muito próximas), elas são mais fáceis de copiar, colar e editar. O que é bom quando se usa o único editor verdadeiro.
Você pode mapear um valor em um intervalo
e, em seguida, use o número de índice desse intervalo em uma instrução case
:
cmil_limits=(320 404 510 642)
index=0
for limit in "${cmil_limits[@]}"
do
if [ "$cmils" -lt "$limit" ]
then
break
fi
((index++))
done
case "$index" in
0) # < 320
cawg="??"
;;
1) # 320-403
cawg="25 AWG"
;;
2) # 404-509
cawg="24 AWG"
;;
3) # 510-641
cawg="23 AWG"
;;
4) # > 641
cawg="??"
;;
esac
Se $cmils
for menor que 320,
nós saímos do loop for
em sua primeira iteração, com index=0
.
Se $cmils
for & nlt; 320 (isto é, ≥ 320),
nós incrementamos index
(→ 1
) e passamos para a próxima iteração.
Então, se $cmils
for < 404 (ou seja, ≤ 403, assumindo que é um número inteiro),
nós saímos do loop com index=1
.
E assim por diante.
Se $cmils
for & nlt; 642, �de 642 e, consequentemente, > 641,
então corremos para o final do loop for
e obtemos index=4
.
Isso tem as vantagens de manter os valores de corte juntos tudo na mesma linha, e você não precisa manter números redundantes (por exemplo, seu código atual e o de outra resposta, listas ambos 403 e 404, e ambos 509 e 510 - que é redundante, e mais trabalho para manter, se os números mudarem. Eu não sei se isso é uma preocupação do mundo real.)
cmil_limits
é uma matriz.
O bash, o ksh e alguns outros shells suportam matrizes, mas outros não.
Se você precisa fazer algo assim em um shell que não suporta matrizes,
você pode simplesmente colocar a lista diretamente na instrução for
:
for limit in 320 404 510 642
do
︙
ou use a lista de parâmetros do shell como uma matriz:
set -- 320 404 510 642
for limit in "$@"
do
︙
Algumas conchas permitem que você abrevie as informações acima:
set -- 320 404 510 642
for limit
do
︙
((…))
aritmética é também um bashismo (como é a instrução let
).
Se você precisa fazer algo assim em um shell
que não suporta ((…))
aritmética,
você pode substituir o
((index++))
Instrução (para incrementar index
) com
index=$(expr "$index" + 1)
Observe que os espaços antes e depois do +
são obrigatórios.