비교 연산자를 사용할 수 있나요?

비교 연산자를 사용할 수 있나요?

전류량, 거리(피트) 및 허용된 전압 강하를 고려하여 필요한 전선 게이지를 계산하는 함수를 구축 중입니다.

이 값이 주어지면 "원형 밀"을 계산할 수 있으며 이로부터 다음을 얻습니다.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

$cmils320보다 작으면 를 사용 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)

앞과 뒤의 공백은 +필수입니다.

관련 정보