web-dev-qa-db-ja.com

Bashで配列をコピーする方法は?

次のように初期化されたアプリケーションの配列があります。

depends=$(cat ~/Depends.txt)

リストを解析し、それを使用して新しい配列にコピーしようとすると、

for i in "${depends[@]}"; do
   if [ $i #isn't installed ]; then
      newDepends+=("$i")
   fi
done

何が起こるかというと、dependsの最初の要素だけがnewDependsになります。

for i in "${newDepends[@]}"; do
   echo $i
done

^^これは1つだけを出力します。だから、なぜforループが最初の要素を動かすだけなのかを理解しようとしています。リスト全体はもともと依存しているので、それはそうではありませんが、私はすべてアイデアから外れています。

46
Kyle R.
a=(foo bar "foo 1" "bar two")  #create an array
b=("${a[@]}")                  #copy the array in another one 

for value in "${b[@]}" ; do    #print the new array 
echo "$value" 
done   
91
user1088530

非連想配列をbashでコピーする最も簡単な方法は次のとおりです。

arrayClone=("${oldArray[@]}")

または、既存の配列に要素を追加するには:

someArray+=("${oldArray[@]}")

要素内の改行/スペース/ IFSは保持されます。

連想配列をコピーするには、Isaacのソリューションが最適です。

20
niieani

他の回答で示された解決策は、連想配列、または非連続インデックスを持つ配列では機能しません。より一般的なソリューションは次のとおりです。

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!')
temp=$(declare -p arr)
eval "${temp/arr=/newarr=}"

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# no output

そしてもう一つ:

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!')
declare -A newarr
for idx in "${!arr[@]}"; do
    newarr[$idx]=${arr[$idx]}
done

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# no output
5

Bash 4. で始まる、これを行うことができます

$ alpha=(bravo charlie 'delta  3' '' foxtrot)

$ declare -n golf=alpha

$ echo "${golf[2]}"
delta  3
2
Steven Penny

インデックスを指定して、最初の配列の要素をコピーに挿入することにより、配列をコピーできます。

#!/bin/bash

array=( One Two Three Go! );
array_copy( );

let j=0;
for (( i=0; i<${#array[@]}; i++)
do
    if [[ $i -ne 1 ]]; then # change the test here to your 'isn't installed' test
        array_copy[$j]="${array[$i]}
        let i+=1;
    fi
done

for k in "${array_copy[@]}"; do
    echo $k
done

この出力は次のようになります。

One
Three
Go!

Bash配列に関する有用なドキュメントは [〜#〜] tldp [〜#〜] にあります。

1
imp25

これを試してください:arrayClone=("${oldArray[@]}")

これは簡単に機能します。

0
maheshk

問題は、親コードで表示されるように関数の配列をコピーすることです。このソリューションはインデックス配列で機能し、コピー前にdeclare -A ARRAY、連想配列でも機能します。

function array_copy
# $1 original array name
# $2 new array name with the same content
{
    local INDEX
    for INDEX in $(eval echo "\${!$1[@]}")
    do
        eval "$2[\"$INDEX\"]=\"\${$1[$INDEX]}\""
    done
}
0
Hiro