script.sh
次のシェルスクリプトがあります。
names=( jack john jerry)
ユーザーは、次のように最初の引数としてこれら3つの名前のいずれかを入力したいと思います。
./script.sh jack
たとえば、ユーザーが文字を誤って入力した場合
./script.sh kate
これはaを実行しexit
、ユーザーにこれら3つのうちの1つだけを入力するように要求します。
どうすればいいですか?
答え1
names=(jack john jerry);
if [[ " "${names[@]}" " == *" "$1" "* ]] ;then
echo "$1: ok"
else
echo "$1: not recognized. Valid names are:"
echo "${names[@]/%/,}"
exit 1
fi
上記のコードはスペースを含まない名前で動作します。
以下の修正バージョンは名前のスペースを処理します。
names=("flash jack" john jerry);
d=$'\1' # validation delimiter - value is \x01
valid="${names[@]/%/$d}"
valid="$d${valid//$d /$d}"
if [[ $valid == *$d$1$d* ]] ;then
echo "$1: ok"
else
echo "$1: not recognized. Valid names are:"
echo "${names[@]/%/,}"
exit 1
fi
空白認識バージョンの出力:
flash jack: ok
または
kate: not recognized. Valid names are:
flash jack, john, jerry,
答え2
これがcase
宣言の目的です。
#! /bin/bash
case $1 in
[Jj]ack)
echo "You chose Jack!"
;;
[Jj]ohn)
echo "You chose John!"
;;
[Jj]erry)
echo "You chose Jerry!"
;;
## For all other cases
*)
echo 'Please choose one of "John", "Jack" or "Jerry"' >&2
exit 1
esac
$1
Caseステートメントは、スクリプトに渡された最初の引数値に基づいて実行されます。jack
またはJack
2 番目の選択が実行され、またはJohn
2john
番目の選択が実行されます。別の項目を入力すると、最後の文が実行されます。
答え3
まず、十分に強力なシェルスクリプトは、悪魔の仕事と見なすことができるモンスターのような配列実装を使用できることに注意する必要があります。また、どのシェルかを示していませんが、bashと仮定します。
これを行うにはいくつかの方法がありますが、すべてが厄介です。
1)配列を繰り返します。読みやすく、比較的クリーンですが非効率的です。
for i in 0 1 2 3 4
do
echo compare ${ARRAY[$i]} perhaps using test or whatever you like
done
2) 一度にすべての操作を実行するには、expr を使用します。これは壊れやすく、ある名前が別の名前の部分文字列の場合は壊れます。この問題は解決できますが、この場合はより良いツールを使用することをお勧めします。
$ ARRAY=(jack john jerry )
$ expr "${ARRAY[*]}" : '.*jack.*'
15 # it's found
$ expr "${ARRAY[*]}" : '.*sue.*'
0 # not found
ここでjackまたはsueは$ 1または確認したいパラメータに置き換えられます。