次の状況を想定します。
#!/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"