Bash スクリプトで配列を変数に割り当てるのはかなり複雑に思えます。
a=("a" "b" "c")
b=$a
echo ${a[0]}
echo ${a[1]}
echo ${b[0]}
echo ${b[1]}
につながる
a
b
a
それ以外の
a
b
a
b
なんで?どうすれば修正できますか?
配列を保持する変数を別の名前にコピーする場合は、次のようにします。
a=('a' 'b' 'c')
b=( "${a[@]}" )
a
が配列の場合、配列$a
の最初の要素に展開されます。b
あなたの例では値が1つしかないのはそのためです。Bash では、配列を参照する変数は、C++ や Java のポインターのように割り当て可能ではありません。代わりに、変数は (パラメーター展開のように) 文字列に展開され、それらの文字列がコピーされ、割り当てられる変数に関連付けられます。
スペースを含む値を含むスパース配列をコピーするには、インデックスによって一度に 1 つの要素を配列にコピーする必要があります。インデックスは ${!a[@]} で取得できます。
declare -a b=()
for i in ${!a[@]}; do
b[$i]="${a[$i]}"
done
bash の man ページから:
配列の値だけでなく、キー (インデックス) も取得できます。${!name[@]} と ${!name[*]} は、配列変数 name に割り当てられたインデックスに展開されます。二重引用符で囲まれている場合の処理は、二重引用符内の特殊パラメーター @ および * の展開に似ています。
自分でテストできるスクリプトを次に示します。
#!/bin/bash
declare -a a=();
a[1]='red hat'
a[3]='fedora core'
declare -a b=();
# Copy method that works for sparse arrays with spaces in the values.
for i in ${!a[@]}; do
b[$i]="${a[$i]}"
done
# does not work, but as LeVar Burton says ...
#b=("${a[@]}")
echo a indicies: ${!a[@]}
echo b indicies: ${!b[@]}
echo "values in b:"
for u in "${b[@]}"; do
echo $u
done
版画:
a indicies: 1 3
b indicies: 1 3 # or 0 1 with line uncommented
values in b:
red hat
fedora core
declare -A
これは、配列を宣言するときに (小文字の代わりに大文字の Aを使用して) 使用すると、bash 4 の連想配列でも機能します。