88

我有一组应用程序,初始化如下:

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

^^ 这只会输出一件事。所以我试图弄清楚为什么我的 for 循环只是移动第一个元素。整个列表最初取决于依赖,所以不是那样,但我完全没有想法。

4

11 回答 11

158
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   
于 2014-06-20T08:44:01.680 回答
38

在 bash 中复制非关联数组的最简单方法是:

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

或将元素添加到预先存在的数组:

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

元素中的换行符/空格/IFS 将被保留。

对于复制关联数组,Isaac 的解决方案效果很好。

于 2016-01-12T00:02:31.940 回答
8

其他答案中给出的解决方案不适用于关联数组或具有非连续索引的数组。这是一个更通用的解决方案:

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
于 2014-08-06T23:02:48.177 回答
5

尝试这个:arrayClone=("${oldArray[@]}")

这很容易工作。

于 2019-06-25T11:57:47.210 回答
2

您可以通过指定索引将第一个数组的元素插入到副本中来复制数组:

#!/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上。

于 2013-10-17T02:27:38.233 回答
1

问题是在函数中复制数组以在父代码中可见。此解决方案适用于索引数组,如果在复制之前预定义为declare -A ARRAY,则也适用于关联数组。

function array_copy
# $1 original array name
# $2 new array name with the same content
{
    local INDEX
    eval "
        for INDEX in \"\${!$1[@]}\"
        do
            $2[\"\$INDEX\"]=\"\${$1[\$INDEX]}\"
        done
    "
}
于 2019-03-04T16:23:40.750 回答
0

Bash 4.3开始,您可以这样做

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

$ declare -n golf=alpha

$ echo "${golf[2]}"
delta  3
于 2015-04-25T23:29:08.250 回答
0
array_copy() {
    set -- "$(declare -p $1)" "$2"
    eval "$2=${1#*=}"
}

# Usage examples:

these=(apple banana catalog dormant eagle fruit goose hat icicle)
array_copy these those
declare -p those

declare -A src dest
source=(["It's a 15\" spike"]="and it's 1\" thick" [foo]=bar [baz]=qux)
array_copy src dest
declare -p dest

注意:复制关联数组时,目标必须已经作为关联数组存在。如果不是,array_copy()则将其创建为标准数组,并尝试将关联源中的键名解释为算术变量名,但结果很难看。

Isaac Schwabacher 的解决方案在这方面更加健壮,但它不能整齐地包装在函数中,因为它的eval步骤评估整个declare语句,而 bash 将它们视为等同于local它们在函数内部时的情况。这可以通过将-g选项嵌入到评估中来解决,declare但这可能会给目标数组提供比它应该拥有的更大的范围。我认为,最好array_copy()只将实际副本执行到明确范围的目标中。

于 2021-12-29T14:54:48.113 回答
0

设法将一个数组复制到另一个数组中。

firstArray=()
secondArray=()

firstArray+=("Element1")
firstArray+=("Element2")

secondArray+=("${firstArray[@]}")

for element in "${secondArray[@]}"; do
  echo "${element}"
done
于 2021-11-24T16:59:08.150 回答
-1

我发现这对我有用(主要是:))......

eval $(declare -p base | sed "s,base,target,")

扩展 sed 命令以根据需要编辑任何开关,例如,如果新结构必须是可写的,则编辑出只读 ( -r)。

于 2021-06-22T15:55:53.843 回答
-4

我发现出了什么问题。我的 if is not installed 测试是两个 for 循环,它们从文件名中删除多余的字符,如果它们存在于某个 Web 服务器上,则将它们吐出。它没有做的是删除尾随连字符。因此,当它在线对其可用性进行测试时,它们被解析出来了。因为“file”存在,但“file-”不存在。

于 2013-10-17T05:31:33.850 回答