43

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

なんで?どうすれば修正できますか?

4

2 に答える 2

69

配列を保持する変数を別の名前にコピーする場合は、次のようにします。

a=('a' 'b' 'c')
b=( "${a[@]}" )
于 2012-09-06T16:01:17.050 に答える
24

なんで?

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 の連想配列でも機能します。

于 2014-08-07T05:22:51.147 に答える