다음 상황을 가정합니다.
#!/bin/sh
case $1 in
e|ex|exa|exam|examp|exampl|example) echo "OK"
;;
t|te|tes|test) echo "Also OK"
;;
*) echo "Error!"
;;
esac
이 상황에 대해 더 우아하고 동시에 POSIX 호환 솔루션이 있습니까(예: bash, zsh 등 없음)?
PS 필요도 없고 exampleeee
일도 Exam
없습니다.
답변1
당신이 할 수 있는 일은 비교를 반대로 하는 것입니다:
case "example" in
"$1"*) echo OK ;;
*) echo Error ;;
esac
여러 단어를 사용하면 원래 아이디어를 고수할 수 있습니다.
case "$1" in
e|ex|exa|exam|examp|exampl|example) : ;;
t|te|tes|test) : ;;
f|fo|foo) : ;;
*) echo error ;;
esac
또는 루프와 "부울" 변수를 사용하세요.
match=""
for word in example test foo; do
case "$word" in
"$1"*) match=$word; break ;;
esac
done
if [ -n "$match" ]; then
echo "$1 matches $match"
else
echo Error
fi
어느 것이 더 나은지 결정하는 것은 당신에게 달려 있습니다. 첫 번째 것은 매우 우아하다고 생각합니다.
답변2
"옵션"을 언급하셨는데요댓글에서, 명령줄 옵션을 구문 분석하려고 하는 것 같습니다. POSIX 유틸리티는 또는 getopts
같은 "긴 옵션"을 구문 분석할 수 없으므로 GNU에 이를 구문 분석하도록 요청할 수 있습니다 .--test
--example
getopt
다음은 짧은 옵션 -e
sum -t
과 해당 "long option" --example
sum 을 사용하는 쉘 스크립트입니다 --test
. 전체 옵션 문자열의 접두사 문자열(예: --e
등) 이 로 --ex
구문 분석되므로 긴 옵션을 명령줄에서 지정할 수 있습니다 --example
. 아래 코드에서 --test
/ 옵션은 해당 긴 옵션 문자열과 뒤따르는 짧은 옵션 문자열로 표시되는 -t
필수 인수를 사용합니다 .:
GNU getopt
( GNU 의 일부 util-linux
)는 명령줄을 구문 분석하는 데 사용됩니다.
#!/bin/sh
opts=$( getopt -o et: -l example,test: -- "$@" )
if [ "$?" -ne 0 ]; then
echo 'Error in getopt' >&2
exit 1
fi
eval set -- "$opts"
unset opts
unset testarg
while true; do
case "$1" in
-e|--example)
echo 'Example option'
shift
;;
-t|--test)
echo 'Test option'
testarg=$2
shift 2
;;
--)
shift
break
;;
*)
echo 'Command line parsing error' >&2
exit 1
esac
done
if [ -n "$testarg" ]; then
printf 'Test argument = "%s"\n' "$testarg"
fi
시험:
$ ./script -e
Example option
$ ./script --exa
Example option
$ ./script --exa -t hello
Example option
Test option
Test argument = "hello"
$ ./script --exa --te='hello world'
Example option
Test option
Test argument = "hello world"
$ ./script -et 'hello world'
Example option
Test option
Test argument = "hello world"
$ ./script -eethello
Example option
Example option
Test option
Test argument = "hello"