アイテムがbash配列にあるかどうかをテストするにはどうすればよいですか?


15

簡単なスクリプトのヘルプ

#!/bin/bash

array1=(
prova1
prova2
slack64
)

a="slack64"
b="ab"

if [ $a = $b ]
then
      echo "$a = $b : a is equal to b"
else
      echo "$a = $b: a is not equal to b"
fi

このスクリプトは単に機能しません。リストにslack64が存在するかどうかを確認し(配列を使用)、yesが存在するかどうかを指定するスクリプトが必要です。配列を単一の変数と比較する方法がわかりません。


4
array1仕事はどこで?
タチョミ

回答:


17

別の種類の配列を使用します。整数インデックス配列ではなく、連想配列を使用します。そのため、キー(インデックス)を確認します。bash-4.0これには、以降が必要です。

declare -A array1=( 
 [prova1]=1  [prova2]=1  [slack64]=1
)

a=slack64
[[ -n "${array1[$a]}" ]] && printf '%s is in array\n' "$a"

上記では、値についてはあまり気にしません。値を空にする必要はありません。キーと値を交換することで、インデックス付き配列を新しい連想配列に「反転」できます。

declare -a array1=( 
 prova1 prova2 slack64
)
declare -A map    # required: declare explicit associative array
for key in "${!array1[@]}"; do map[${array1[$key]}]="$key"; done  # see below

a=slack64
[[ -n "${map[$a]}" ]] && printf '%s is in array\n' "$a"

連想配列の実装は、配列を横断するループよりも優れたパフォーマンスを発揮するため、頻繁に検索される大きな配列がある場合は、これで十分です。ただし、重複を処理できないため(上記のように値を1つだけではなくカウンターとして使用できます)、空のインデックスを処理できないため、すべてのユースケースに適しているわけではありません。

「反転」を説明するために、上記の複雑な行を分割します。

for key in "${!a[@]}"     # expand the array indexes to a list of words
do 
  map[${a[$key]}]="$key"  # exchange the value ${a[$key]} with the index $key
done

14

簡単な方法は、ループで繰り返すことです:

var=ab
for item in "${array[@]}"; do
    [[ $var == "$item" ]] && echo "$var present in the array"
done

[[ a == aaa ]]は偽ですが、一致するaaa no?
ジルケノー

SO OPは次のように、彼は値が特殊文字を含めることができるかどうか世話をしなければならないことを知らされるべき[ ]:文字クラス(グロブ)
ジルQuenot

[[ ]]あなたが言ったことについて、bash で=と==の間に違いはありません。テストしましたか?
ジルケノー


2

この関数は連想配列で機能します。

この関数を使用して、次のいずれかを実行できます。

-配列に特定のキーがあるかどうかを確認します-----------------> inArray "myKey" $ {!myArray [@]} "

-配列に特定の値が含まれているかどうかを確認します---------> inArray "myValue" "$ {myArray [@]}"

function inArray # ( keyOrValue, arrayKeysOrValues ) 
{
  local e
  for e in "${@:2}"; do 
    [[ "$e" == "$1" ]] && return 0; 
  done
  return 1
}

declare -A arr
arr[doo]=55

inArray "doo" "${!arr[@]}"
echo $?     # 0 
inArray "bla" "${!arr[@]}"
echo $?     # 1 
inArray "55" "${arr[@]}"
echo $?     # 0

2

そのためにgrepを使用することもできます。

array1 =(prova1 prova2 slack64)
a = slack64
if(printf '%s \ n' "$ {array1 [@]}" | grep -xq $ a); それから
    エコー「それは」
fi

1
これは、配列要素に改行文字が含まれていないことを前提としています(引用符を忘れたときに空白とワイルドカードを使用$a-、を忘れたときに開始しないでください--)。%s\0代わりに%s\ngrep --nullbash変数にはNUL文字を含めることができないため、GNU grepまたは互換性があると仮定して使用できます。また、空の配列のケースを特別に処理する必要があります(printfコマンドは、1つの空の要素を持つ配列と同じものを出力するため)。また、ここでサブシェルを開始する必要はありません。
ステファンシャゼル

はい、問題のような単純な配列に適用できます。
ペトルケトナー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.