아래와 같이 변수가 4자리 이상인지 테스트하고 싶습니다.
#!/bin/bash
if [ $input has more than 4 digits ]; then
echo " * Please only 4 digits" >&2
echo""
else
the other option
fi
답변1
(숫자 값보다는) 비트 수에 관심이 있다면 Bash/Ksh/Zsh의 정규 표현식과 일치시킬 수 있습니다 (*각주 참조 [[:digit:]]
) .
#!/bin/bash
input=$1
re='^[[:digit:]]{1,4}$'
if [[ $input =~ $re ]]; then
echo "'$input' contains 1 to 4 digits (and nothing else)"
else
echo "'$input' contains something else"
fi
또는 예를 들어 [[ $input =~ ^[[:digit:]]{5,}$ ]]
"5개 이상의 숫자(다른 숫자 없음)" 등을 확인합니다.
case
또는 순수 POSIX 셸에서는 패턴 일치를 사용해야 합니다 .
#!/bin/sh
input=$1
case $input in
*[![:digit:]]*) onlydigits=0;; # contains non-digits
*[[:digit:]]*) onlydigits=1;; # at least one digit
*) onlydigits=0;; # empty
esac
if [ $onlydigits = 0 ]; then
echo "'$input' is empty or contains something other than digits"
elif [ "${#input}" -le 4 ]; then
echo "'$input' contains 1 to 4 digits (and nothing else)"
else
echo "'$input' contains 5 or more digits (but nothing else)"
fi
(모든 로직을 안에 넣을 수 있지만 case
, if
거기에 중첩시키는 것은 제 생각에는 약간 보기 흉합니다.)
이는 [[:digit:]]
현재 로케일의 "숫자" 개념과 일치해야 합니다. 이는 ASCII 숫자를 초과할 수도 있고 초과하지 않을 수도 있습니다 0123456789
. 내 시스템에서는 [[:digit:]]
⁴(위 첨자 4, U+2074)가 일치하지 않지만 [0-9]
일치합니다. 다른 "숫자"를 일치시키는 것은 문제가 될 수 있습니다. 쉘의 숫자에 대해 산술 연산을 수행하는 경우. 따라서 더 엄격하게 적용하려면 [0123456789]
ASCII 숫자만 허용을 사용하세요.
답변2
이는 ASCII 십진수만을 의미하고 다른 유형의 십진수 또는 십진수가 아닌 숫자는 의미하지 않는다고 가정합니다.
shopt -s extglob # enables a subset of ksh extended globs including *(...),
# +(...) and ?(...) but unfortunately not {4}(...)
d='[0123456789]' nd='[^0123456789]'
case $input in
( $d$d$d$d+($d) ) echo made of more than 4 digits;;
( *$d*$d*$d*$d*$d* ) echo contains more than 4 digits;;
( "" ) echo empty;;
( *($nd) ) echo does not contain any digit;;
( *$nd* ) echo no more than 4 digits but also contains non-digits;;
( $d?($d)?($d)?($d) ) echo made of 1 to 4 digits;;
( * ) echo should not be reached;;
esac
bash
시스템 및 로캘 에 따라 0123456789 이상과 일치할 수 있으므로 입력 유효성 검사에 사용해서는 안 됩니다(자세한 내용 [0-9]
은[[:digit:]]
이것은 다른 질문에 대한 답변입니다예를 들어).
또한bash
패턴 일치는 멀티바이트 로케일에서 매우 놀라운 방식으로 작동합니다..
예를 들어 zh_CN.gb18030
중국어 로케일 에서는 input='1-©©'
예상대로 반환되지만 단일 바이트( ) no more than 4 digits but also contains non-digits
를 추가하면 반환됩니다 .0x80
input='1-©©'$'\x80'
contains more than 4 digits
이러한 이유(그리고 많은 쉘의 코너 케이스에서 패턴 일치가 버그가 있다는 사실) 때문에 입력 유효성 검사를 위해 가능할 때마다 허용하는 것에 대해 (부정적 일치보다는) 긍정적인 일치(부정적 일치와 반대)를 사용하는 것이 더 좋습니다. ) 거부하려는 항목에 대해) 1 따라서 $d?($d)?($d)?($d)
필수는 아니지만 적어도 이론적으로는 다른 항목이 이전 패턴과 일치해야 합니다.
1 예외적으로 Bourne 및 Korn 쉘의 단점을 고려할 수도 있습니다. 이 쉘 case $input in [x]) echo yes; esac
은 !x
[x]
답변3
내가 할게
#!/usr/bin/env bash
die () { echo "$*" >&2; exit 1; }
input=$1
[[ $input == +([[:digit:]]) ]] || die "only digits please"
(( input <= 9999 )) || die "no more than 4 digits please"
echo "ok: $input"
답변4
또 다른 방법은 다음과 같습니다.
#!/bin/bash
if test -z "$1"
then
echo no digit supplied
elif grep -qE '[[:digit:]]{5}' <<< "$1"
then
echo too many digits supplied
else
echo number of digits ok
fi