스크립트에 전달 된 인수가 숫자인지 확인하는 방법을 알 수 없습니다.
내가하고 싶은 것은 다음과 같습니다.
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]+$`