전류량, 거리(피트) 및 허용된 전압 강하를 고려하여 필요한 전선 게이지를 계산하는 함수를 구축 중입니다.
이 값이 주어지면 "원형 밀"을 계산할 수 있으며 이로부터 다음을 얻습니다.AWG 요구 사항. 나는 원형 밀을 그들의 존경받는 사양과 비교하는 큰 성명을 작성하기 시작했지만 이것이 올바른 도구라고 if
elif
믿습니다 .case
숫자를 비교하는 사례를 찾지 못했기 때문에 다음과 같이 할 수 있는지 궁금합니다.
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...
}
답변1
POSIX 쉘
산술 테스트를 찾고 있는데 케이스가 산술을 수행하지 않으므로 이는 if-then
자연스러운 접근 방식처럼 보입니다.
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
치명타만 발생
나는 휴대용 솔루션을 선호하지만 일부 사람들은 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
POSIX 구문보다 강력하지만 취약하기도 합니다. 이유를 이해하려면 설정 후 이 코드를 사용해 보세요 cmils=cmils
.
답변2
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"
;;
답변3
다른 사람들이 말했듯 case
이 비교 연산자는 지원되지 않으며 전역 패턴 일치만 지원됩니다.
그러나 if/elif/fi 문 세트를 만들 수 있습니다.바라보다사례 설명과 비슷하지만 형식이 다릅니다. 예를 들어 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
심지어:
[ "$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'
노트:이 변형의 단점은 사용된 것과 달리 elif
적어도 각 행의 첫 번째 테스트가 실행된다는 것입니다 . elif
테스트가 true로 평가된 후 를 사용하면 나머지 모든 테스트를 건너뜁니다. 그런 것을 함수에 넣고 && return
설정한 후에 추가 할 수 있습니다 cawg
.
나는 개인적으로 둘 중 하나가 더 읽기 쉽다고 생각하지만(추가 줄 바꿈이나 번갈아 들여쓰기로 인해 상황이 복잡해지지 않음), 이 특정 코딩 스타일/들여쓰기 문제에 대한 의견은 매우 다양합니다. :)
모든 항목이 동일한(또는 매우 가까운) 열에 정렬되므로 복사, 붙여넣기 및 편집도 더 쉽습니다. 실제 편집기를 사용할 때 유용합니다.
답변4
값을 범위에 매핑한 다음 명령문에서 해당 범위의 인덱스 번호를 사용할 수 있습니다 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
$cmils
320보다 작으면 를 사용 for
하여 첫 번째 반복에서 루프를 종료합니다 index=0
. $cmils
≮ 320(즉, ≥ 320)이면 증가 index
(→ 1
)하고 다음 반복을 계속합니다. 그런 다음 $cmils
< 404(즉, 정수라고 가정하면 ≤ 403)인 경우 루프를 종료합니다 index=1
. 등. ≮ 642 이면 $cmils
≥ 642이므로 > 641이므로 루프 끝까지 실행하여 for
를 얻습니다 index=4
.
이것의 장점은 컷오프를 모두 같은 줄에 유지하고 중복 번호를 유지할 필요가 없다는 것입니다(예: 현재 코드와 다른 답변 코드 모두 403을 나열함).그리고404, 동시에 509그리고510 - 이는 중복되며 번호가 변경되면 더 많은 유지 관리가 필요합니다. 이것이 현실 세계의 관심사인지는 모르겠습니다. )
cmil_limits
배열입니다. bash, ksh 및 기타 일부 쉘은 배열을 지원하지만 일부는 그렇지 않습니다. 배열을 지원하지 않는 셸에서 비슷한 작업을 수행해야 하는 경우 목록을 명령문에 직접 넣을 수 있습니다 for
.
for limit in 320 404 510 642
do
︙
또는 쉘의 인수 목록을 배열로 사용하십시오.
set -- 320 404 510 642
for limit in "$@"
do
︙
일부 쉘에서는 위의 내용을 단축할 수 있습니다.
set -- 320 404 510 642
for limit
do
︙
((…))
산술은 또한 bashism의 한 형태이기도 합니다( let
성명에서 알 수 있듯이). arithmetic 을 지원하지 않는 쉘에서 비슷한 작업을 수행해야 하는 경우 ((…))
다음을 대체할 수 있습니다.
((index++))
명령문 (증가 index
)
index=$(expr "$index" + 1)
앞과 뒤의 공백은 +
필수입니다.