태그 보관물: integer

integer

문자열이 유효한 정수인지 테스트 문자별로 구분할 필요가 없습니다. 이게

나는 셸 스크립트에서 사용자 입력을 구문 분석하는 것입니다. 사용자가 유효한 정수를 제공 한 경우 스크립트는 한 가지 작업을 수행하고 유효하지 않은 경우 다른 작업을 수행합니다. 문제는이 작업을 수행하는 쉽고 (합리적으로 우아한) 방법을 찾지 못했다는 것입니다. 문자별로 구분할 필요가 없습니다.

이게 쉬울 거라는 건 알지만 방법은 모르겠어요. 12 개 언어로 할 수 있지만 BASH는 아닙니다!

내 연구에서 나는 이것을 발견했습니다.

문자열이 10 진법의 유효한 실수로 구성되어 있는지 테스트하기위한 정규식

그리고 거기에 정규식에 대해 이야기하는 대답이 있지만 내가 아는 한 그것은 C에서 사용할 수있는 함수입니다. 그래도 좋은 대답처럼 보였기 때문에 grep으로 시도했지만 grep은 어떻게 해야할지 몰랐습니다. 나는 내 상자에서 PERL 정규 표현식으로 취급한다는 것을 의미하는 -P를 시도했습니다. 대시 E (-E)도 작동하지 않았습니다. 그리고 -F도 마찬가지입니다.

명확하게 말하면, 나는 이와 같은 것을 시도하고, 출력을 찾고 있습니다. 거기에서 내가 얻는 모든 것을 활용하기 위해 스크립트를 해킹 할 것입니다. (IOW, 유효한 라인이 반복되는 동안 부적합한 입력은 아무것도 반환하지 않을 것으로 예상했습니다.)

snafu=$(echo "$2" | grep -E "/^[-+]?(?:\.[0-9]+|(?:0|[1-9][0-9]*)(?:\.[0-9]*)?)$/")
if [ -z "$snafu" ] ;
then
   echo "Not an integer - nothing back from the grep"
else
   echo "Integer."
fi

누군가 이것이 가장 쉬운 방법을 설명해 주시겠습니까?

솔직히 이것은 TEST의 단점이라고 생각합니다. 다음과 같은 플래그가 있어야합니다.

if [ -I "string" ] ;
then
   echo "String is a valid integer."
else
   echo "String is not a valid integer."
fi



답변

[[ $var =~ ^-?[0-9]+$ ]]
  • ^입력 패턴의 시작을 나타낸다
  • -리터럴 “-“
  • ?수단 “0 또는 1 항 ( -)”
  • +수단 “앞의 1 이상 ( [0-9])”
  • $입력 패턴의 끝을 나타낸다

따라서 정규식은 선택 사항 -(음수의 경우)과 그 뒤에 하나 이상의 십진수를 일치 시킵니다.

참고 문헌 :


답변

와우 … 여기에 좋은 해결책이 너무 많습니다 !! 위의 모든 솔루션 중에서 -eq하나의 라이너 를 사용하는 것이 가장 멋지다는 @nortally에 동의합니다 .

GNU bash, 버전 4.1.5(Debian)을 실행 중 입니다. ksh (SunSO 5.10)에서도 이것을 확인했습니다.

$1정수인지 아닌지 확인하는 내 버전은 다음과 같습니다 .

if [ "$1" -eq "$1" ] 2>/dev/null
then
    echo "$1 is an integer !!"
else
    echo "ERROR: first parameter must be an integer."
    echo $USAGE
    exit 1
fi

이 접근법은 또한 다른 솔루션 중 일부가 잘못된 음수 결과를 갖는 음수를 설명하며 분명히 정수인 “+”(예 : +30) 접두사를 허용합니다.

결과 :

$ int_check.sh 123
123 is an integer !!

$ int_check.sh 123+
ERROR: first parameter must be an integer.

$ int_check.sh -123
-123 is an integer !!

$ int_check.sh +30
+30 is an integer !!

$ int_check.sh -123c
ERROR: first parameter must be an integer.

$ int_check.sh 123c
ERROR: first parameter must be an integer.

$ int_check.sh c123
ERROR: first parameter must be an integer.

Ignacio Vazquez-Abrams가 제공 한 솔루션은 설명 된 후에도 매우 깔끔했습니다 (정규식을 좋아한다면). 그러나 +접두사 가있는 양수를 처리하지 않지만 다음과 같이 쉽게 수정할 수 있습니다.

[[ $var =~ ^[-+]?[0-9]+$ ]]


답변

여기 파티에 후발. 가장 간단하고 빠르며 휴대 성이 뛰어난 솔루션을 언급 한 답변이 없다는 사실에 매우 놀랐습니다. case문.

case ${variable#[-+]} in
  *[!0-9]* | '') echo Not a number ;;
  * ) echo Valid number ;;
esac

비교하기 전에 모든 기호를 잘라내는 것은 약간의 해킹처럼 느껴지지만 case 문에 대한 표현이 훨씬 간단 해집니다.


답변

-eq테스트를 사용하는 솔루션이 마음에 듭니다. 기본적으로 한 줄짜리이기 때문입니다.

내 해결책은 매개 변수 확장을 사용하여 모든 숫자를 버리고 남은 것이 있는지 확인하는 것이 었습니다. (저는 아직 3.0을 사용하고 있으며 사용하지 않았 [[거나 expr이전에 사용했지만 만나서 반갑습니다.)

if [ "${INPUT_STRING//[0-9]}" = "" ]; then
  # yes, natural number
else
  # no, has non-numeral chars
fi


답변

Bash 3.1 이전 버전으로의 이식성을 위해 ( =~테스트가 도입 되었을 때 ) expr.

if expr "$string" : '-\?[0-9]\+$' >/dev/null
then
  echo "String is a valid integer."
else
  echo "String is not a valid integer."
fi

expr STRING : REGEXSTRING의 시작 부분에 고정 된 REGEX를 검색하여 첫 번째 그룹 (또는 일치하지 않는 경우 일치 길이)을 반영하고 성공 / 실패를 반환합니다. 이것은 오래된 정규식 구문이므로 초과 \. -\?“아마도 -“를 [0-9]\+의미하고 “하나 이상의 숫자”를 $의미하며 “문자열의 끝”을 의미합니다.

Bash는 또한 확장 된 glob을 지원하지만 어떤 버전에서 이후 버전인지 기억하지 못합니다.

shopt -s extglob
case "$string" of
    @(-|)[0-9]*([0-9]))
        echo "String is a valid integer." ;;
    *)
        echo "String is not a valid integer." ;;
esac

# equivalently, [[ $string = @(-|)[0-9]*([0-9])) ]]

@(-|)-또는 아무것도”를 [0-9]의미하고 “숫자”를 *([0-9])의미하며 “0 개 이상의 숫자”를 의미합니다.


답변

여기에 또 다른 방법이 있습니다 (테스트 내장 명령과 반환 코드 만 사용).

function is_int() { return $(test "$@" -eq "$@" > /dev/null 2>&1); }

input="-123"

if $(is_int "${input}");
then
   echo "Input: ${input}"
   echo "Integer: $[${input}]"
else
   echo "Not an integer: ${input}"
fi


답변

숫자가 아닌 것을 제거하고 비교할 수 있습니다. 다음은 데모 스크립트입니다.

for num in "44" "-44" "44-" "4-4" "a4" "4a" ".4" "4.4" "-4.4" "09"
do
    match=${num//[^[:digit:]]}    # strip non-digits
    match=${match#0*}             # strip leading zeros
    echo -en "$num\t$match\t"
    case $num in
        $match|-$match)    echo "Integer";;
                     *)    echo "Not integer";;
    esac
done

테스트 출력은 다음과 같습니다.

44 44 정수
-44 44 정수
44-44 정수 아님
4-4 44 정수 아님
a4 4 정수 아님
4a 4 정수 아님
.4 4 정수 아님
4.4 44 정수 아님
-4.4 44 정수 아님
09 9 정수 아님