【问题标题】:Multidimensional associative arrays in BashBash 中的多维关联数组
【发布时间】:2011-09-03 05:29:31
【问题描述】:

我正在尝试创建一个多维关联数组,但需要一些帮助。我已经查看了the page suggested in this SO answer,但它让我更加困惑。到目前为止,这是我所拥有的:

脚本:

#!/bin/bash
declare -A PERSONS
declare -A PERSON
PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
PERSONS["1"]=${PERSON[@]}
PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
PERSONS["2"]=${PERSON[@]}
for KEY in "${!PERSONS[@]}"; do
 TMP="${PERSONS["$KEY"]}"
 echo "$KEY - $TMP"
 echo "${TMP["FNAME"]}"
 echo "${TMP["LNAME"]}"
done

输出:

1 - John Andrew
John Andrew
John Andrew
2 - Elen Murray
Elen Murray
Elen Murray

如您所见,尝试在 for 循环中访问 $TMP 数组的特定索引会返回整个数组。

[Q] 我需要做什么才能在for 循环内分别访问 $TMP 数组的“FNAME”和“LNAME”索引?

谢谢。

【问题讨论】:

标签: bash hash multidimensional-array hashtable associative-array


【解决方案1】:

我了解您的需求。我也想要同样的几个星期。 我很困惑是使用 Python 还是 Bash。 最后,探索其他东西我发现了这个 Bash: How to assign an associative array to another variable name (e.g. rename the variable)?

在这里,我知道了如何分配一些字符串并稍后将其用作命令。 然后凭借我的创造力,我找到了解决您问题的方法如下:-


#!/bin/bash

declare -A PERSONS
declare -A PERSON

PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
string=$(declare -p PERSON)
#printf "${string}\n"
PERSONS["1"]=${string}
#echo ${PERSONS["1"]}

PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
string=$(declare -p PERSON)
#printf "${string}\n"
PERSONS["2"]=${string}
#echo ${PERSONS["2"]}

for KEY in "${!PERSONS[@]}"; do
   printf "$KEY - ${PERSONS["$KEY"]}\n"
   eval "${PERSONS["$KEY"]}"
   printf "${PERSONS["$KEY"]}\n"
   for KEY in "${!PERSON[@]}"; do
      printf "INSIDE $KEY - ${PERSON["$KEY"]}\n"
   done
done

输出:-

1 - 声明 -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'

声明 -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'

在 FNAME 内部 - 约翰

在 LNAME 内部 - 安德鲁

2 - 声明 -A PERSON='([FNAME]="Elen" [LNAME]="Murray" )'

声明 -A PERSON='([FNAME]="Elen" [LNAME]="Murray" )'

在 FNAME 内部 - 艾伦

在 LNAME 内部 - 穆雷


在 bash 中,特别是在您的方法中,多维数组的实际问题是,您将 PERSON 数组值分配给数组元素 PERSONS[1],当您分配它时,该数组元素被转换为列表而不是 assoc 数组。 因此,它不再将其视为数组的 2 个元素,因为您没有在值中保留有关数组数据结构的任何信息。 所以,我发现这个 hack 就足够了,只有 1 个限制,每次你想要存储/检索值时都必须这样做。但它会解决你的目的。

【讨论】:

  • niccccccce.. 我希望我使用 python !!1
【解决方案2】:

你不能做你想做的事:bash arrays 是一维的

$ declare -A PERSONS
$ declare -A PERSON
$ PERSON["FNAME"]='John'
$ PERSON["LNAME"]='Andrew'
$ declare -p PERSON
declare -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'
$ PERSONS[1]=([FNAME]="John" [LNAME]="Andrew" )
bash: PERSONS[1]: cannot assign list to array member

您可以通过组合合适的数组索引字符串来伪造多维性:

declare -A PERSONS
declare -A PERSON

PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
i=1
for key in "${!PERSON[@]}"; do
  PERSONS[$i,$key]=${PERSON[$key]}
done

PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
((i++))
for key in "${!PERSON[@]}"; do
  PERSONS[$i,$key]=${PERSON[$key]}
done

declare -p PERSONS
# ==> declare -A PERSONS='([1,LNAME]="Andrew" [2,FNAME]="Elen" [1,FNAME]="John" [2,LNAME]="Murray" )'

【讨论】:

  • 我尝试了您的解决方案,但这不是我想要的,因为当我遍历 $PERSONS 时,我按以下顺序获得这 4 个元素:“1,LNAME = Andrew”,“2,FNAME = Elen”、“1,FNAME = John”和“2,LNAME - Murray”,我无法使用。我仍然对为什么 bash 不能支持多维数组感到困惑。归根结底,我所做的只是将一个变量($PERSON 数组)分配给一个数组元素($PERSONS["X"])。为什么这个变量 i 的类型很重要? bash 是否检查并防止将数组分配给数组元素?
  • @user359650,这是 bash 开发人员的设计决定。引用我的 bash 手册:“Bash 提供一维索引和关联数组变量。”您正在做的是将字符串(“John Andrew”)分配给数组索引。我认为您需要重新审视自己在做什么——如果您绝对必须拥有多维数组,那么您使用的工具是错误的。
  • 另外,关联数组没有特定的顺序。
【解决方案3】:
#!/bin/bash
declare -A PERSONS
declare -A PERSON
PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
PERSONS["1"]=${PERSON[@]}
PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
PERSONS["2"]=${PERSON[@]}
for KEY in "${!PERSONS[@]}"; do
 TMP="${PERSONS["$KEY"]}"
 echo "$KEY - $TMP"
 **echo "${PERSON["FNAME"]}"
 echo "${PERSON["LNAME"]}**"
done

因为单独名称的原始数组仍然处于活动状态,并且仍然可以在 for 循环中引用。

【讨论】:

  • 对不起,我不明白你的解决方案。我不想访问 $PERSON 数组,因为一旦创建了 $PERSONS 就不再需要访问它了。
  • 道歉 - 我已经阅读了我的解决方案,但它是错误的,我稍后会回来
猜你喜欢
  • 1970-01-01
  • 2013-01-25
  • 2021-05-23
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
相关资源
最近更新 更多