【问题标题】:Copy a bash associative array using eval statement使用 eval 语句复制 bash 关联数组
【发布时间】:2020-10-12 11:41:02
【问题描述】:

在我们进入这个问题之前,我知道在堆栈溢出时已经有类似的答案了。然而,这个是独一无二的,因为它使用带有关联数组的 eval 语句。 (相信我,我都读过)。

好的,现在进入问题

我有 X 个通过类似下面的 eval 函数定义的数组:

for (( i=1;i<=X;i++ ))
do
   eval "declare -gA old$i"
   eval "old$i[key]=value"
done

此代码在函数中:makeArrays

现在我有第二个函数必须遍历这些不同的数组

old1
old2
.
.
.
oldX

我会调用这个函数:useArrays

现在,我有一个用于这个 useArrays 函数的 for 循环。

for (( i=0;i<$#;i++ ))
do
  // ACCESS OLD1[KEY]
done

我的问题是,我如何访问这个数组进行比较。 IE。 如果 [ 旧 1 -eq 0 ] 然后 ... 菲

有没有办法可以将这些关联数组复制到一个变量中,以便尽可能少地使用 eval 进行比较?

【问题讨论】:

  • 比较...什么?整个阵列一次?单个键?
  • 另外,哪个特定版本的 bash?如果您使用的是带有 namerefs 的版本,那么有更好的(不需要评估)方法来完成所有这些操作。
  • 如果 old1 是一个数组,那么将它与一个数字进行比较是什么意思?是否要检查所有元素是否相同?您能否提供一个更具体的失败示例?
  • old1[path] -eq '/path/to/file' 将是我想要使用的比较。
  • 使用版本 4.4.19

标签: linux bash rhel8


【解决方案1】:

现代版本的 bash 支持 namerefs(最初是 ksh 功能),因此您可以将常量名称指向您选择的任何变量;这使得 eval 对于您当前放置它的目的来说是不必要的。

key="the key you want to test"
for (( i=0;i<$#;i++ )); do
  declare -n "oldArray=old$i"  # map the name oldArray to old0/old1/old2/...
  printf 'The value of %q in old%q is: %q\n' "$key" "$i" "${oldArray[$key]}"
  unset -n "oldArray"          # remove that mapping
done

你当然可以参考"${!oldArray[@]}" 来迭代它的键;还映射一个newArray namevar 进行比较;等等

【讨论】:

  • 所以对于关联数组的每个键,我需要运行一个 for 循环。这似乎超级低效。
  • 您能否更详细地解释其他两个选项?我已经阅读了堆栈溢出答案,其中提到了您在此处解释的内容,但对于我的情况似乎并不可行。特别是因为旧数组被赋予了唯一的数字。
  • 这个问题提到了key,但没有从任何地方提出来。因此,我假设您只想比较一个键。
  • ...老实说,如果您想比较整个关联数组,我只需使用 declare -p 将整个内容转换为字符串并删除前面)。仍然不需要eval
猜你喜欢
  • 2023-03-06
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多