这个问题已经被问过好几次了,但是没有一个方法有效。我想动态创建数组,其数组名称取自变量。所以现在我们只从一个数组开始:
#!/bin/bash
i="aaa"
eval ${i}=("1")
结果是
./1.sh: line 3: syntax error near unexpected token `('
./1.sh: line 3: `eval ${i}=("1")'
与以下结果相同:
$(eval ${i})=('1')
$(eval echo ${i})=('1')
$(eval "echo ${i}")=('1')
我不想评估所有内容,只想评估数组名称。如果可能的话我想完全避免使用 eval
答案1
eval
需要一个字符串作为参数。不能使用(
不带引号的,它在 shell 中有特殊的含义。
i=aaa
eval "$i=(1 2)" # Use a string, $i will expand in double quotes.
echo ${aaa[1]}
您还可以使用declare
ortypeset
代替eval
:
declare -a $i='(1 2)'
您仍然需要引用括号和空格。
为了eval
完全避免,可以一一赋值:
#! /bin/bash
name=aaa
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
read "$name[$i]" <<< "${values[i]}"
done
echo ${aaa[1]}
答案2
这是一种不使用 来加载数组的方法eval
。它不使用( data )
构造 - 相反,它使用输入字符串和您选择的分隔符 - 该示例使用|
i=aaa
IFS='|' read -a "$i" <<<"1|2 with spaces"
printf '%s\n' "${aaa[@]}"
输出:
1
2 with spaces
答案3
您可以使用declare
动态名称和值以及变量间接来根据变量的名称来引用变量。 printf '%q'
可以帮助您“外壳转义”值,以便可以在动态分配期间使用它们。
#!/bin/bash
declare -a products=( phone computer )
printf 'Product: %s\n' "${products[@]}"
# Product: phone
# Product: computer
unset products
declare varName='products'
declare -a "${varName}"='( cell\ phone laptop\ computer )'
declare arrayRef="${varName}[@]"
printf 'Product: %s\n' "${!arrayRef}"
# Product: cell phone
# Product: laptop computer
unset "${varName}"
declare -a toCopy=( 'LED TV' '"Smart" car' )
declare -a "${varName}"="( $( printf '%q ' "${toCopy[@]}" ) )"
printf 'Product: %s\n' "${!arrayRef}"
# Product: LED TV
# Product: "Smart" car
unset "${varName}"