ループ内の配列要素を一つおきに列挙する

ループ内の配列要素を一つおきに列挙する

キーペア値を持つ動的配列があり、列挙したいのですがほかのすべてのseq値。この場合、配列内の名前だけです。私は bash v4 を使用していないので、 echo を使用して配列をステップ実行できました。

$ array=(Guido yes Francesca no Balthazar yes)
for x in $(seq 0 2 ${#array[@]});do echo $x;done
0
2
4
6

これは、私が持っているペアよりも 1 つ多い要素を返します (オフセットが 0 のため)。ただし、単純な bash の計算を使用してこれを説明できます。

for x in $(seq 0 2 $((${#array[@]}-1)));do echo $x;done
0
2
4

これはうまく動作します。しかし、要素を から取り出そうとすると$array、説明できないエラーが発生します。私は「math」の有無で試しました。

$ for x in $(seq 0 2 $((${#array[@]}-1)));do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

$ for x in $(seq 0 2 ${#array[@]});do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

この動的配列から名前だけを取得するにはどうすればよいでしょうか?

編集:私の$BASH_VERSION3.2.57(1)-releaseMac OS X 10.10.2

編集#2:これはおそらくこのバージョンのバグであるという結論に達しました。私は多数の AWS インスタンスを管理しているので、それらをチェックすることにしました。それらはすべて bash 4.1.2(1) です。Mac をこのバージョンにアップグレードしたら、動作するようになりました。ご覧いただきありがとうございます。しかし、これは異常な現象であると考えています。

答え1

配列の代替要素をループしたい場合は、bash 3.2 で次のコードが動作するはずです。

while IFS= read -d '' -r name; do
  # do something with "$name"
done < <(printf %s%.0s\\0 "${array[@]}")

xargs -0もっと便利であれば、同様のことを実行できます。

たとえば、名前にコロンが含まれていない場合は、次のように名前を新しい配列に抽出できます。

IFS=: read -a names -r < <(printf %s%.0s: "${array[@]}")

(残念ながら、フィールドセパレーターを NUL に設定することはできません。)

printfこれらはすべて、 がすべての引数を使用するのに必要な回数だけフォーマット文字列を繰り返すという事実に依存しています(Posix の動作なので、任意の bash バージョン、または非組み込み で動作するはずですprintf)。 時々役立つ format は%.0s、引数を使用し、そこから最大 0 文字を出力します。つまり、引数をビットバケットにドロップします。

関連情報