bash:引数から関数への配列名を取得し、インデックスを保存します。

bash:引数から関数への配列名を取得し、インデックスを保存します。

選択した要素のインデックスを表示する機能があります。配列名として使用するために関数にパラメータを渡したいと思います。これは働きます:

getIndex() {
arrname=$1[@]
b=("${!arrname}")
index=1; while ((index<${#b[@]})); do
    if [[ "${b[$index]}" = "$VALUE" ]]; then
        echo "index is $index"; return
    fi  
        ((index++)); done

}

ただし、関数に渡した名前の配列には、最初の要素のインデックスとしてインデックス1があります(配列からパターンを取得できる行番号に似たインデックスが必要です。

a=1
while read line; do
    if [[ $line =~ ^[0-9] ]]; then
        avg[$a]=`echo $line | awk '{print $6}'`
        ((a++));    
    fi

getIndex() 関数を実行すると、配列の最初の要素がインデックス 0 から始まります。

もしそうなら、質問は:パラメータの配列名を関数に渡し、配列インデックスを保存する方法はありますか?あるいは、単に忘れて関数応答に+1を追加する必要があるかもしれません。

ベストアンサー1

次の構造を使用しています。

b=("${!arrname}")

これは拡張されます価値配列、新しいb[]配列を作成するBash デフォルトの配列インデックスは 0 から始まります。。配列のコピーを適切に初期化するには、インデックスを復元する必要があります(eval出力を解析または-ingするなどdeclare -p arrname)。

コピーする代わりに、より良いアプローチは拡張することです。索引値の代わりにそれを使用して配列を繰り返します。このアプローチは、希薄または非ゼロベースの標準配列(bash4連想配列を含む)で機能します。

問題(常に存在するわけではない)は!二重任務を遂行するということです。間接参照での使用は${!name}拡張配列索引付けでの使用と互換性がないため、を使用する必要が${!arrname[@]}ありますeval

この機能を実装する修正バージョンは次のとおりです。

getIndex2() {
  local arrname=$1 iidx idxs index ival val
  printf -v iidx '"${!%s[@]}"' "$arrname"
  eval "idxs=($iidx)"
  for index in "${idxs[@]}"; do
    printf -v ival '${%s[%s]}' "$arrname" "$index"
    eval "val=$ival"
    if [[ "${val}" = "$VALUE" ]]; then
        echo "index is $index"; return   
    fi
  done
}

可読性を最大限にprintf -v var ...維持するには、(bash-3.1+)を使用してください。evalインデックスは配列に展開されます。必ずしも必要ではなく、単純なリストも機能します。

また、見ることができますバッシュFAQ/006

おすすめ記事