文字列値が配列要素と一致するかどうかをテストする

文字列値が配列要素と一致するかどうかをテストする

私はbashスクリプトを使用しており、カンマで区切られた値文字列がありますstring="string1,string2,string"。各文字列にはコンマやスペースは含まれていません。文字列要素が配列にあるかどうかをテストしたいと思います。

文字列要素を任意の配列の要素と一致させるには?

string="element1,element2,element3"
array=($(echo $string | tr ',' ' '))
for i in "${array[@]}"; do
    if [ "$i" == "element2" ]; then
        echo "element found"
    fi
done

答え1

おそらく次のようにすることができます:

string=element1,element2,element3
element=element2
case ",$string," in
  (*,"$element",*) echo element is in string;;
  (*) echo it is not;;
esac

(標準sh構文).

配列操作や文字列分割の場合、bashはシェルの中で最悪の選択肢の1つです。

zsh特定の区切り文字に文字列を分割するには、専用の演算子であるsplitがあります。パラメータ拡張フラグ:

array=( "${(@s[,])string}" )

(Bourneシェルの@ように空の要素を保存するために引用符を使用)"$@"

配列に与えられた要素があることを確認してください。

if (( $array[(Ie)$element] )); then
  print element is in the array
else
  print it is not
fi

分割するには、ksh / shのように、bash分割+glob演算子(引用符なしで使用するのは少し厄介です)を使用できます。$(...)

IFS=, # split on , instead of the default of SPC/TAB/NL
set -o noglob # disable the glob part which you don't want
array=( $string'' ) # split+glob; '' added to preserve an empty trailing element
                    # though that means an empty $string is split into one empty
                    # element rather than no element at all

配列を見つけるためにbashには専用の演算子はありませんが、ヘルパー関数を定義できます。

is_in() {
  local _i _needle="$1"
  local -n _haystack="$2"
  for _i in "${_haystack[@]}"; do
    [ "$_i" = "$_needle" ] && return
  done
  false
}
if is_in "$element" array; then
  echo element is in the array
else
  it is not
fi

答え2

有効な単語リストのハッシュテーブルを設定し、(効果的に)2番目のリストのすべての項目を検索できます。

#! /bin/bash
#.. ./LookUp  04-Feb-2023: Paul_Pedant.

declare -A Hash     #.. Create at global scope.

Setup () {      #.. Set up a hash table of the required elements.

    local j; declare -a q
    #.. Make the input string into an array like: q=([0]="Monday" ...)
    IFS=, read -r -a q <<<"${1}"
    #.. Invert that array like: Hash([Monday]="0" ...)
    for j in "${!q[@]}"; do Hash+=(["${q[j]}"]="${j}"); done
}

Query () {      #.. Search for words in a list. 

    local s; declare -a q
    IFS=, read -r -a q <<<"${1}"
    for s in "${q[@]}"; do
        if [[ -z "${Hash[${s}]+x}" ]]; then
            printf '%s is missing\n' "${s}"
        else    
            printf '%s is index %s\n' "${s}" "${Hash[${s}]}"
        fi      
    done
}

    Setup "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"

    Query "Tuesday,BadHairDay,Friday,Holiday,Sunday,Today,Monday,BadDay"

そしてテストしてください:

$ ./LookUp 
Tuesday is index 1
BadHairDay is missing
Friday is index 4
Holiday is missing
Sunday is index 6
Today is missing
Monday is index 0
BadDay is missing
$ 

答え3

あなたの質問を正しく理解し、csvを配列に変換するビットを無視すると、次のようになります。時々配列内の要素を検索するのに役立ちますが、潜在的な空白/改行文字やその他の文字に関していくつかの注意があります。

arr=(foo bar baz)
if [[ "${arr[*]}" =~ foo ]]; then
  echo "element found"
fi

答え4

私は次の解決策を持っています

aggr=("bash" "resource" "rsync")
ukeys="resource,rsync"

if [[ "${aggr[@]}" =~ $(echo "$ukeys" | tr ',' '|') ]]; then
  echo "All strings exist in the array."
else
  echo "One or more strings do not exist in the array."
fi

このtrコマンドは、文字列のカンマをパイプで置き換えて、=~演算子で使用できる正規表現を生成するコマンドを使用します。この$( ... )構文は tr コマンドを実行して出力をキャプチャするために使用され、その後=~演算子のパターンとして使用されます。正規表現が配列の要素と一致すると、配列内のすべての文字列が配列内にあることを示すifブロックが実行されます。

ukeysの要素がarrayの要素と一致するaggr場合display=1

関連情報