回答:
Bash 4では、連想配列を使用できます。
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
最初に配列を設定するには、直接割り当てを行うこともできます。
array[foo]=1
array[bar]=1
# etc.
またはこの方法:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
は簡単ですが、問題がありset -u
ます。スクリプトで使用する場合(推奨)、「非バインド変数」を取得するため、機能しません。
これは古い質問ですが、最も簡単な解決策はまだ登場していないと思いますtest ${array[key]+_}
。例:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
出力:
a is set
b is set
この作品はチェック方法を確認するには、これを。
env
では、「test」という名前を採用した可能性のあるエイリアス、プログラム、およびその他の関数のあいまいさを避けるために使用することをお勧めします。上記のようにenv test ${xs[a]+_} && echo "a is set"
。ダブルブラケットを使用してこの機能を取得することもできます。同じトリックを使用してnullをチェックします[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
連想配列の要素が存在する(設定されていない)かどうかをテストする方法があります。これは空とは異なります。
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
次にそれを使用します:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1
=に注意してくださいsome_check
。だから:isNotSet() { [[ ... ]] }
。以下の私の解決策を確認してください、あなたは簡単なチェックでそれを行うことができます。
配列の内容をgrepにパイプすることで、エントリが存在するかどうかを確認できます。
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
一致の行番号を返すgrep -nを使用してエントリのインデックスを取得することもできます(1を減算してゼロベースのインデックスを取得することを忘れないでください)。これは非常に大きな配列を除いてかなり高速です。
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
説明:
$( ... )
コマンドの出力を変数にキャプチャするためにバックティックを使用するのと同じです printf
mydataを1行に1要素出力します @
です。*.
これに加えて、「hello world」を2行に分割することを避けます)grep
正確な文字列を検索します: ^
そして、$
行頭と行末に一致しますgrep -n
4:hello worldの形式で行番号を返します grep -m 1
最初の一致のみを検索しますcut
行番号のみを抽出します もちろん、減算をコマンドに組み込むことができます。ただし、欠落がないか-1をテストします。
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
整数演算を行います配列内のデータが非常に限られている場合を除き、ループせずに適切に実行できるとは思わない。
これは単純なバリアントの1つです。これは"Super User"
、配列に存在することを正しく示しています。しかし、それは"uper Use"
配列内にもあると言うでしょう。
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
問題は、配列をループする以外に、アンカーを追加する簡単な方法(考えられること)がないことです。配列に入れる前に追加できない限り...
grep "\b$FINDME\b"
)良い解決策です。おそらくで、何のスペースを持っていない英数字以外の定数で仕事ができる"(^| )$FINDME(\$| )"
(またはそのような何か...私は正規表現のgrepの用途の何味を学ぶことができたことはありません)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array
。乾杯
${ARRAY[@]}
使用する必要があります。