case + in case 구문과 같거나 작거나 큼을 구현하는 방법

case + in case 구문과 같거나 작거나 큼을 구현하는 방법

case내 목표는 (only + ) 를 사용하여 숫자 범위의 유효성을 검사 esac하고 범위를 인쇄하는 것입니다. 예를 들어:

  • 숫자가 0에서 80 사이이면 인쇄합니다.>=0<=80
  • 숫자가 81에서 100 사이이면 인쇄하십시오.>=81<=100
  • 등.

아래 스크립트의 문제점은 >=0<=900에서 9 사이의 숫자만 인쇄한다는 것입니다. 숫자 범위에 따라 올바른 출력을 인쇄하도록 스크립트를 수정하려면 어떻게 해야 합니까?

#!/bin/ksh
read number 
case $number in 
 [0-80])  echo ">=0<=80";; 
 [81-100]) echo ">=81<=100";; 
 [101-120]) echo ">=101<=120";;
 [121-300]) echo ">=121<=300";;
esac

답변1

case패턴 일치에만 사용되며 산술 평가를 수행하지 않습니다( zsh<x-y>확장 패턴 일치 연산자를 고려하지 않는 한). 그냥 [...]어울리려고하나문자(또는요소 구성일부 구현에서는) 거기에 지정된 컬렉션을 기반으로 합니다. 예를 들어 [0-80]다음과 같습니다.하나0to 8또는 중 하나 인 경우 문자입니다 0(예: 0, 1, 2, 3, 4, 5, 6, 7, 8 중 하나).

다음 패턴으로 숫자를 일치시킬 수 있습니다.

case $(($number)) in
  ([0-9]|[1-7][0-9]|80) echo ">=0<=80";;
  (8[1-9]|9[0-9]|100) echo ">=81<=100";;
  ... and so on
esac

그러나 이것이 올바른 도구가 아니라는 것을 쉽게 알 수 있습니다.

[...]경쟁하나문자를 지정된 문자 목록에 대해 비교하므로 [121-300]1, 2, 1에서 3, 0 또는 0까지의 모든 문자와 일치하므로 [0-3]또는 와 동일 합니다 [0123].

사용:

if [ "$number" -ge 0 ] && [ "$number" -le 80 ]; then
  echo ">=0<=80"
elif [ "$number" -ge 81 ] &&  [ "$number" -le 100 ]; then
  echo ">=81<=100"
elif ... and so on
  ...
fi

또 다른 사용 방법은 case다음과 같습니다.

case $((
  (number >= 0 && number <= 80)   * 1 +
  (number > 80 && number <= 100)  * 2 +
  (number > 100 && number <= 120) * 3 +
  (number > 120 && number <= 300) * 4)) in
  (1) echo ">=0<=80";;
  (2) echo ">=81<=100";;
  (3) echo ">=101<=120";;
  (4) echo ">=121<=300";;
  (0) echo "None of the above";;
esac

또는 삼항 연산자( x ? y : z)를 사용합니다.

case $((
  number >= 0 && number <= 80   ? 1 :
  number > 80 && number <= 100  ? 2 :
  number > 100 && number <= 120 ? 3 :
  number > 120 && number <= 300 ? 4 : 0)) in...

아니면 @mikeserv처럼 고정관념에서 벗어나 생각해보세요.case논리를 뒤집어 1이러한 산술 비교 값을 일치시킵니다..

답변2

실제로 해보면 정말 쉽습니다. 문제는 case항상 패턴과 일치하는 첫 번째 항목을 찾는 데 필요한 크기만 확장한다는 것입니다. 이는 표준 동작입니다. 따라서 알려진 문자열로 설정하고 패턴의 확장을 평가하면 됩니다.

case  1:${number:--} in
(1:*[!0-9]*|1:0*[89]*)
  ! echo NAN
;;
($((number<81))*)
    echo "$number >=0<=80"
;;
($((number<101))*)
    echo "$number >=81<=100"
;;
($((number<121))*)
    echo "$number >=101<=120"
;;
($((number<301))*)
    echo "$number >=121<=300"
;;
esac

case패턴에서 선행 1을 찾으려면 이러한 패턴이 확장되지 않습니다. 이는 사용자 입력을 처리할 때 특히 중요합니다. 이는 $number실제로 수학 확장에 넣는 것과 동일한 컨텍스트인 산술 확장 컨텍스트에 넣기 전에 내용을 안전하게 검증 할 수 있다는 의미입니다 .

답변3

별로 좋지는 않지만 다음을 사용할 수 있습니다.

 #!/bin/ksh

read number  

case $number in
[0-9]|[1-7][0-9]|80) echo  echo ">=0<=80";;
8[1-9]|9[0-9]|100) echo ">=81<=100";;
10[1-9]|11[0-9]|120) echo ">=101<=120";;
12[1-9]|130) echo ">=121<=300";;
esac

관련 정보