【问题标题】:Dynamic array name in bashbash 中的动态数组名
【发布时间】:2021-07-19 07:19:16
【问题描述】:

因为 bash 不支持“数组中的数组”, 我试图在调用数组时动态化变量名。

bash 版本:4.2

我使用了这种扩展方式:https://stackoverflow.com/a/18124325/9336478

#!/bin/bash
# data are pre-defined and type is determined later

declare -a data_male
declare -a data_female

data_male=(value1 value2)
data_female=(value3 value4)

type="male" 

for value in ${${!data_$type}[@]};do
  echo $value
done

它没有工作

line 20: ${${!data_$type}[@]} : bad substitution

我该如何解决这个问题?

【问题讨论】:

  • 你使用的是哪个版本的 Bash?
  • @vdavid 我目前正在使用 4.2 编辑帖子
  • 您不能像这样在单个步骤中嵌套扩展,您需要将变量设置为您想要扩展的内容(其中包括 [@] 之类的内容以获取数组的所有元素)。类似data_type_contents="data_${type}[@]"; for value in ${!data_type_contents}; do ...
  • 您是否可以选择安装更新版本的bash

标签: arrays bash variable-names


【解决方案1】:

不幸的是,在 Bash 4.2 中,您需要 eval 数组。

printf -v evaluator 'for value in ${%s[@]};do\n  echo $value\ndone' "data_$type"
eval "$evaluator"

printf会将data_$type指定的数组名称注入%s部分,然后将字符串的结果赋值给变量evaluator

因此,第一部分构建了一个设计用于评估的字符串,然后您对其进行评估。

除了换行符\n,您还可以使用实际换行符:

printf -v evaluator 'for value in ${%s[@]};do
  echo $value
done' "data_$type"
eval "$evaluator"

您应该确保数组的内容是安全的,因为这可能会被用来注入恶意代码。

【讨论】:

    【解决方案2】:

    如果 OP 可以安装较新版本的 bash,则可以使用 nameref(名称参考,在 bash 4.3+ 中可用):

    declare -a data_male
    declare -a data_female
    
    data_male=(value1 value2)
    data_female=(value3 value4)
    
    type="male"
    
    declare -n arr="data_${type}"       # dynamically declare arr[] as a name ref to data_male[]
    
    for ndx in "${!arr[@]}"
    do
        echo "${arr[${ndx}]}"
    done
    

    这会生成:

    value1
    value2
    

    【讨论】:

      猜你喜欢
      • 2018-07-22
      • 2017-11-06
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      相关资源
      最近更新 更多