大きなインデックスを持つbash配列を起動するとどうなりますか?

大きなインデックスを持つbash配列を起動するとどうなりますか?

bash "多次元"配列を作成しようとしているときに連想配列を使用するアイデアを見ましたが、最も簡単な方法は次のとおりです。

for i in 0 1 2
do 
    for j in 0 1 2
    do
        a[$i$j]="something"
    done
done

値を設定して取得するのは簡単ですが、bashがインデックス00から22まで順番に要素にスペースを割り当てる場合(つまり、{0,1,2,3,4,...,21,22}の位置を割り当てます)意味)、そうではありません。実際の要素のセット:{00,01,02,10,11,...,21,22}。

インデックス"n"でbash配列を起動すると、何が起こるのか疑問に思います。インデックス0からnまでに十分なスペースを割り当てますか、それともn番目の要素カテゴリを別々に割り当てますか?

答え1

bashの配列索引付けとkshの配列索引付け(bashの配列設計の複製)は、任意の算術式にすることができます。

では、および変数が拡張されている算術式としてbashで8進数1を表現することa[$i$j]="something"になります。それではと同じです。あなたは得るだろうと 。$i$ji=0 j=1a[01]="something"01i=0 j=10a[010]="something"a[8]="something"a[110]="something"x=11 y=0x=1 y=10

今これはあなたが望むものではないことが明らかになりました。

代わりに、Cのように2D配列(行列)で作業できます。

matrix_size=3
for (( i = 0; i < matrix_size; i++ )) {
  for (( j = 0; j < matrix_size; j++ )) { 
    a[i * matrix_size + j]="something"
  }
}

for (( ...; ...; ...))ksh93からコピーされたCと同様の構成)。

または、多次元配列をサポートするksh93に切り替えます。

for (( i = 0; i < 3; i++ )) {
  for (( j = 0; j < 3; j++ )) { 
    a[i][j]="something"
  }
}

キーが文字列である連想配列を使用して多次元配列を実装することもできます。

typeset -A a
for (( i = 0; i < 3; i++ )) {
  for (( j = 0; j < 3; j++ )) { 
    a[$i,$j]="something"
  }
}

レポートによると、3つすべてで得られる結果変数は次のとおりですtypeset -p

  1. declare -a a=([0]="something" [1]="something" [2]="something" [3]="something" [4]="something" [5]="something" [6]="something" [7]="something" [8]="something")
    
  2. typeset -a a=((something something something) (something something something) (something something something) )
    
  3. declare -A a=([0,2]="something" [0,1]="something" [0,0]="something" [2,1]="something" [2,0]="something" [2,2]="something" [1,2]="something" [1,0]="something" [1,1]="something" )
    

今のトピックの質問に答えるには、kshと同様に、bashでも通常の配列が希薄です。つまり、定義せずに定義できるため、Cや他のほとんどのa[n]言語の配列やシェルとは異なります。a[0]a[n-1]

元のkshでは、配列インデックスの制限は4095だったので、最大64 x 64のサイズの行列を持つことができましたが、この制限はその後4,194,303に増えました。 ksh93では、これによりa[4194303]=132MiB以上のメモリが割り当てられることがわかります。 4194304 64ビットポインタと少しオーバーヘッドが節約されるようです。一方、bash配列インデックスが9223372036854775807ほど高くなる可能性があるksh93では、これは起こらないようです(少なくともGNU / Linux amd64)、実際の設定要素を格納するのに必要なメモリよりも多くのメモリを割り当てません。

配列((t)csh、zsh、rc、es、fish ...)をサポートする他のすべてのシェルでは、配列インデックスはゼロではなく1から始まり、配列は大文字と小文字がないと設定できない一般的な非希少配列です。空の文字列に設定されていてもa[2]設定されます。a[1]

ほとんどのプログラミング言語と同様に、Bashの連想配列は、順序や階層の概念なしでハッシュテーブルとして実装されています(typeset -p上からランダムな順序で表示されることがわかります)。

さまざまなシェルの配列設計の詳細については、次を参照してください。この回答到着アレイのテストシェルのサポート

関連情報