与えられたパラメータが与えられた配列にあるかどうかを確認するには?

与えられたパラメータが与えられた配列にあるかどうかを確認するには?

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

$1Caseステートメントは、スクリプトに渡された最初の引数値に基づいて実行されます。jackまたはJack2 番目の選択が実行され、またはJohn2john番目の選択が実行されます。別の項目を入力すると、最後の文が実行されます。

答え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または確認したいパラメータに置き換えられます。

関連情報