[linux] Bash에서 변수가 숫자인지 어떻게 테스트합니까?

스크립트에 전달 된 인수가 숫자인지 확인하는 방법을 알 수 없습니다.

내가하고 싶은 것은 다음과 같습니다.

test *isnumber* $1 && VAR=$1 || echo "need a number"

어떤 도움?



답변

한 가지 방법은 다음과 같이 정규식을 사용하는 것입니다.

re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
   echo "error: Not a number" >&2; exit 1
fi

값이 반드시 정수가 아닌 경우 정규식을 적절히 수정하십시오. 예를 들어 :

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

… 또는 부호가있는 숫자를 처리하려면 :

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


답변

bashisms없이 (System V sh에서도 작동)

case $string in
    ''|*[!0-9]*) echo bad ;;
    *) echo good ;;
esac

이것은 빈 문자열과 숫자가 아닌 문자열을 거부하고 다른 모든 것을 허용합니다.

음수 또는 부동 소수점 숫자는 추가 작업이 필요합니다. 아이디어는 첫 번째 “나쁜”패턴에서 -/ 를 제외 .하고 부적절한 사용 ( ?*-*/ *.*.*)을 포함하는 “나쁜”패턴을 더 추가하는 것입니다 ( / )


답변

정규식없이 Bourne과 같은 기본 쉘에서 다음 솔루션을 사용할 수도 있습니다. 기본적으로 숫자가 아닌 숫자를 사용하는 숫자 값 평가 작업은 오류를 발생시키고 셸에서 암시 적으로 false로 간주됩니다.

"$var" -eq "$var"

에서와 같이 :

#!/bin/bash

var=a

if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
  echo number
else
  echo not a number
fi

당신은 또한 $를 테스트 할 수 있습니까? 보다 명백한 오퍼레이션의 리턴 코드 :

[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
   echo $var is not number
fi

표준 오류의 리디렉션은 숫자가없는 경우 bash가 출력하는 “정수 식 예상”메시지를 숨기는 것입니다.

주의 사항 (아래 의견 감사) :

  • 소수점이있는 숫자는 유효한 “숫자”로 식별 되지 않습니다.
  • [[ ]]대신에 사용 [ ]하면 항상true
  • 비 Bash 쉘은 대부분이 표현식을 다음과 같이 평가합니다. true
  • Bash의 동작은 문서화되어 있지 않으므로 경고없이 변경 될 수 있습니다.
  • 숫자에 공백이 포함 된 경우 (예 : “1 a”) 다음과 같이 오류가 발생합니다. bash: [[: 1 a: syntax error in expression (error token is "a")
  • 값이 var-name과 같은 경우 (예 : i = “i”) 다음과 같은 오류가 발생합니다. bash: [[: i: expression recursion level exceeded (error token is "i")

답변

이것은 숫자가 음이 아닌 정수이고 쉘과 독립적이며 (bashisms 없음) 쉘 내장만을 사용하는지 테스트합니다.

부정확합니다.

이 첫 번째 대답 (아래)은 변수에서 첫 번째가 아닌 한 문자가있는 정수를 허용합니다.

[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";

맞습니다 .

질 (Jilles)그의 답변 에서 언급하고 제안한 것처럼 , 이것은 쉘 패턴을 사용하여 올바른 방법입니다.

[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";


답변

아무도 bash의 확장 패턴 일치를 제안하지 않았습니다 .

[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"


답변

쉘에서 숫자 형식을 직접 구문 분석하는 솔루션에 놀랐습니다. 쉘은 파일과 프로세스를 제어하기위한 DSL 인 이것에 적합하지 않습니다. 예를 들어 다음과 같이 충분한 수의 파서가 있습니다.

isdecimal() {
  # filter octal/hex/ord()
  num=$(printf '%s' "$1" | sed "s/^0*\([1-9]\)/\1/; s/'/^/")

  test "$num" && printf '%f' "$num" >/dev/null 2>&1
}

‘% f’를 필요한 특정 형식으로 변경하십시오.


답변

나는 대답을보고 있었고 … 아무도 플로트 번호에 대해 생각하지 않았다는 것을 깨달았습니다 (점 포함)!

grep을 사용하는 것도 좋습니다.
-E는 확장 된
expexp를
의미합니다. -q는 조용함을 의미합니다 (반향되지 않음)
.

명령 행에서 직접 테스트하려면 다음을 수행하십시오.

$ echo "32" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is: 32

$ echo "3a2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is empty (false)

$ echo ".5" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer .5

$ echo "3.2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is 3.2

bash 스크립트에서 사용 :

check=`echo "$1" | grep -E ^\-?[0-9]*\.?[0-9]+$`

if [ "$check" != '' ]; then
  # it IS numeric
  echo "Yeap!"
else
  # it is NOT numeric.
  echo "nooop"
fi

JUST 정수와 일치 시키려면 다음을 사용하십시오.

# change check line to:
check=`echo "$1" | grep -E ^\-?[0-9]+$`