Bash配列に値が含まれているかどうかを確認する方法

Bash配列に値が含まれているかどうかを確認する方法

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

#!/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がリストにあることを確認し(私は配列を使用しています)、それが存在するか存在しないかを単に知らせるスクリプトが必要です。配列を単一の変数と比較する方法がわかりません。

答え1

異なるタイプの配列を使用してください。整数インデックス配列の代わりに連想配列を使用します。したがって、確認したいのはキー(インデックス)です。bash-4.0または後で行う必要があります。

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

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

上記では、私たちは実際に値を気にしないだけで、nullではありません。キーと値を交換することで、インデックス配列を新しい連想配列に「反転」することができます。

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

答え2

最も簡単な方法は、ループを使用して繰り返すことです。

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

答え3

Bash配列に値が含まれているかどうかを確認する方法


偽の肯定一致

array=(a1 b1 c1 d1 ee)

[[ ${array[*]} =~ 'a' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'a1' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'e' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'ee' ]] && echo 'yes' || echo 'no'
# output:
yes

完全にフィット

正確に一致する項目を見つけるには、正規表現パターンに値の前後に余分なスペースを含める必要があります。(^|[[:space:]])"VALUE"($|[[:space:]])

# Exact match

array=(aa1 bc1 ac1 ed1 aee)

if [[ ${array[*]} =~ (^|[[:space:]])"a"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
No

if [[ ${array[*]} =~ (^|[[:space:]])"ac1"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

find="ac1"
if [[ ${array[*]} =~ (^|[[:space:]])"$find"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

より多くの使用例については、サンプルソースをご覧ください。ここ

答え4

そしてzsh

array1=(
  prova1
  prova2
  slack64
)

a=slack64

if (( $array1[(Ie)$a] )); then
  printf '%s\n' "$a in array1"
fi

配列I添字フラグは、一致の最も右側の要素のインデックスを返すために使用されます$a(見つからない場合は0)。eこれはパターンマッチングではなく、正確な/リテラル​​マッチングです。


そしてbash

Bashの配列メンバーにはNULバイト(zshとは反対)を含めることができないため、GNUまたは互換バージョンがある場合はgrepいつでも次のことができます。

if (( ${#array1[@]} )) && printf '%s\0' "${array1[@]}" | grep -zqxFe "$a"; then
  printf '%s\n' "$a in array1"
fi

つまり、NULで区切られた要素を印刷し、これらのeroで区切られたレコードに格納されている式に一致する固定文字列をgrepすばやく見つけるように要求します。qxFe$az

関連情報