사례 패턴을 부정하는 방법

사례 패턴을 부정하는 방법

조건을 추가하려면 어떻게 해야 하며, 필요한 조건이 감지되지 않으면 명령이 실행됩니다.

내 코드:

case $price in
[0-9] | "." | "$") echo "Numbers, . , $ Only"
            ;;
esac

숫자 "."가 감지되면 이 명령이 실행됩니다. 그리고 "$". 이들 중 아무것도 감지되지 않으면 어떤 의미에서 이를 변경하는 방법에 따라 명령이 실행됩니다. 아니면 이 기능을 수행하는 데 사용할 수 있는 더 나은 명령이 있습니까?

답변1

기본 케이스 추가:

case $price in
[0-9] | "." | "$") true
            ;;
*) 
   do-something
   ;;
esac

답변2

case이 답변은 이미 설명한 문제가 아니라 일치 문제를 의미합니다 .

먼저 유효한 문자열이 어떻게 생겼는지 정의해야 합니다. 물론 가장 간단한 정의는 하나의 구조만 허용합니다.

  1. 하나 이상의 숫자로 시작합니다(앞에 0이 허용됨).
  2. 소수점
  3. 후행 두 자리 숫자(필요한 경우 00)
  4. 달러 기호(앞에 공백 없음)

정규식( 예 grep참조 man 7 regex)으로 다음과 같이 작성됩니다.

^[0-9]+\.[0-9][0-9]\$$
  • ^문자열의 시작을 표시합니다. 즉, 문자열 앞에는 아무것도 올 수 없습니다.[0-9]+
  • \.포인트는 리터럴 포인트로 처리되도록 이스케이프됩니다 .
  • 달러 기호는 \$문자 그대로 받아들여질 수 있도록 이스케이프 처리됩니다.
  • 후행은 $문자열의 끝을 표시합니다. 즉, 텍스트 뒤에는 아무 것도 올 수 없습니다.$

시험:

> echo '0123.45$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
0123.45$

점과 후행 숫자가 있는 달러 기호가 모두 선택 사항이 되도록 정의를 변경하면 정규식은 다음과 같이 변경됩니다.

^[0-9]+(\.[0-9][0-9])?\$?$

시험:

> echo '0123$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'

# no match
> echo '0123$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123$
> echo '0123.45$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123.45$

쉘은 정규식을 직접 사용할 수 있지만 case패턴 내에서는 사용할 수 없습니다. 구조가 필요합니다 [[ ]]. 그러나 문자열이 일치하는지 알고 싶기 때문에 다음을 사용할 이유가 없습니다 case.

if [[ "$price" =~ ^[0-9]+(\.[0-9][0-9])?\$?$ ]]; then
  :
else
  :
fi

정말로 필요한 경우 쉘 bulitin을 사용하여 case옵션을 설정하고 정규식을 "쉘 정규식"으로 다시 작성할 수 있습니다.extglobshopt

shopt -s extglob

^[0-9]+(\.[0-9][0-9])?\$?$그러면 그것은 된다

+([0-9])?(.[0-9][0-9])?($)

선두 $

대신 원한다면 처음부터 확인 $0123.45해야 합니다 .0123.45$$

  • grep/ [[ ]]:^\$?[0-9]+(\.[0-9][0-9])?$
  • 쉘 패턴 일치:?($)+([0-9])?(.[0-9][0-9])

확인하기 더 쉽다

순서는 중요하지 않고 올바른 문자만 고려한다면 더 간단한 표현식을 사용할 수 있습니다.

  • grep/ [[ ]]:^[0-9.$]+$
  • 쉘 패턴 일치:+([0-9.$])

#! /bin/bash

shopt -s extglob

for value in 1234 1234EUR; do
    case "$value" in
            +([0-9]))
                    echo "value OK: '${value}'"
            ;;
            *)
                    echo "value not OK: '${value}'"
            ;;
    esac
done

답변3

단일 양의 정수만 포함하는 문자열을 쉘 문과 일치시키려면 case다음을 수행할 수 있습니다.

case "${string:--}" in
(*[!0-9]*)  
! echo 'Invalid value for $string!';;
(*[!0]*) 
echo "$string is a positive integer greater than 0.";;
(*)
echo "$string is 0.";;
esac

첫 번째 일치에서는 포함되지 않은 확장 값(단일 문자라도 포함)을 case필터링합니다 . 설정 되지 않거나 비어 있으면 이 패턴으로 확장되므로 여전히 이 패턴과 일치합니다. 리드 반전 반환${string:--}0123456789$string-!echo(항상 0)1로 - 따라서 유효하지 않은 값이 포함된 경우 case구성은 1을 반환합니다 .$string

$string다음으로, 0이 아닌 한 자리 숫자를 포함하는 모든 값 과 일치합니다 . 따라서 유효한 값의 앞에 오는 0의 개수는 $string양수로 일치합니다.

마지막 항목은 처음 두 항목과 일치하지 않는 모든 항목과 일치합니다. 즉, 하나 이상의 0만 일치합니다.

관련 정보