Arrays bash中是否有一个array_combine函数,我可以从两个数组中创建一个关联数组?

Arrays bash中是否有一个array_combine函数,我可以从两个数组中创建一个关联数组?,arrays,linux,bash,samba,Arrays,Linux,Bash,Samba,我有两个数组,一个是用户名,另一个是全名,它们实际上是由wbinfo-u动态生成的 USR=(user1 user2 user3) FULL=("full user 1" "full user 2" "full user 3") 我想创建一个关联数组,我可以将它与pdbedit一起使用,因此在循环中我将创建/修改用户名和全名(在PHP中使用起来很容易) 没有现成的数组组合例程,但您可以通过以下方式欺骗它: USR=(user1 user2 user3) FULL=("full user 1"

我有两个数组,一个是用户名,另一个是全名,它们实际上是由wbinfo-u动态生成的

USR=(user1 user2 user3)
FULL=("full user 1" "full user 2" "full user 3")
我想创建一个关联数组,我可以将它与pdbedit一起使用,因此在循环中我将创建/修改用户名和全名(在PHP中使用起来很容易)


没有现成的数组组合例程,但您可以通过以下方式欺骗它:

USR=(user1 user2 user3)
FULL=("full user 1" "full user 2" "full user 3")

declare -A arr
eval "$(paste -d= <(printf 'arr[%q]\n' "${USR[@]}") <(printf '%q\n' "${FULL[@]}"))

没有现成的数组组合例程,但您可以通过以下方式欺骗它:

USR=(user1 user2 user3)
FULL=("full user 1" "full user 2" "full user 3")

declare -A arr
eval "$(paste -d= <(printf 'arr[%q]\n' "${USR[@]}") <(printf '%q\n' "${FULL[@]}"))

您可以仅使用bash 4.3内置函数()自行实现此功能,如下所示:

combine() {
  declare key_no key val
  declare -n _keys=$1 _vals=$2 _dest=$3
  declare -g -A "$3"
  for key_no in "${!_keys[@]}"; do
    key=${_keys[$key_no]}
    val=${_vals[$key_no]}
    _dest[$key]=$val
  done
}

usr=(user1 user2 user3)
full=("full user 1" "full user 2" "full user 3")

combine usr full arr
这个版本通过一些额外的偏执来正确处理稀疏数组


如果您需要支持4.3之前的bash版本(理想情况下是4.3系列后期,因为存在影响namevar支持的安全漏洞,可能会导致早期4.3版本中的任意代码执行),那么下面的代码使用
declare
稍微谨慎一些(感谢您提出此解决方案,而不是之前仔细使用
eval
的方法):

combine(){
声明键\u var=$1 VAL\u var=$2结果\u var=$3
声明间接i键
声明-gA“$result\u var”
间接=“${keys_var}[@]”键=(“${!indirect}”)
对于((i=0;i<${keys[@]};i++),do
间接=“${vals\u var}[$i]”声明-g“${result\u var}[${keys[i]}]=${!间接}”
完成
}

您可以仅使用bash 4.3内置软件()自行实现此功能,如下所示:

combine() {
  declare key_no key val
  declare -n _keys=$1 _vals=$2 _dest=$3
  declare -g -A "$3"
  for key_no in "${!_keys[@]}"; do
    key=${_keys[$key_no]}
    val=${_vals[$key_no]}
    _dest[$key]=$val
  done
}

usr=(user1 user2 user3)
full=("full user 1" "full user 2" "full user 3")

combine usr full arr
这个版本通过一些额外的偏执来正确处理稀疏数组


如果您需要支持4.3之前的bash版本(理想情况下是4.3系列后期,因为存在影响namevar支持的安全漏洞,可能会导致早期4.3版本中的任意代码执行),那么下面的代码使用
declare
稍微谨慎一些(感谢您提出此解决方案,而不是之前仔细使用
eval
的方法):

combine(){
声明键\u var=$1 VAL\u var=$2结果\u var=$3
声明间接i键
声明-gA“$result\u var”
间接=“${keys_var}[@]”键=(“${!indirect}”)
对于((i=0;i<${keys[@]};i++),do
间接=“${vals\u var}[$i]”声明-g“${result\u var}[${keys[i]}]=${!间接}”
完成
}


如果内容包含literal
$()
之类的内容,这安全吗?@CharlesDuffy不,这根本不安全。可以通过
eval修复”$(paste-d=@gniourf\u gniourf:非常感谢,我明白了你的要点。我应该使用
%q
而不是
%s
eval
中加引号。对于包含文字
$()
之类内容的情况,这安全吗?@CharlesDuffy不,这根本不安全。可以用
eval>来修复。”$(paste-d=@gniourf\u gniourf:非常感谢,我明白了你的要点。我应该使用
%q
而不是
%s
eval
中加引号。仅供参考,所有大写名称都保留给环境变量和shell内置;遵守此约定可以防止命名空间冲突。谢谢你的提醒。仅供参考,所有大写名称都是大写的。)名称是为环境变量和shell内置项保留的;遵守此约定可以防止名称空间冲突。感谢您的提醒。谢谢。第二种方法对我很有效,因为我的bash版本在一台机器上是4.2.37,在另一台机器上是4.3.30。很高兴这有帮助!顺便说一句,我刚刚又看了一眼,意识到我对decl有点马虎使用局部变量;这两个版本现在应该更好(不再将
key
val
泄漏到全局范围)..第二个版本使用@glenn jackman建议的更好的方法再次更新。它正在工作,但是,当我运行for循环时,它将每个数组的所有项作为一个项。因此usr中的所有名称都被视为一个名称,full也会这样。我可以猜这是因为引号,甚至使用awk the r围绕着引号结果是一样的。如果你使用
declare-p usr
declare-p full
,它是否会将它们显示为包含多个不同项的数组?如果不是,我建议问一个新问题,重点是如何填充这些数组,并提供足够的详细信息来重现问题。请随意在这里添加链接;我很想看看said问题!谢谢。第二种方法对我很有效,因为我的bash版本在一台机器上是4.2.37,在另一台机器上是4.3.30。很高兴这有帮助!顺便说一句,我刚刚又看了一眼,意识到我在声明局部变量方面有点马虎;现在这两个版本都应该更好了(不再将
val
泄漏到全局范围)..第二个版本使用@glenn jackman建议的更好的方法再次更新。它正在工作,但是,当我运行for循环时,它将每个数组的所有项作为一个项。因此usr中的所有名称都被视为一个名称,full也会这样。我可以猜这是因为引号,甚至使用awk the r围绕着引号结果是一样的。如果你使用
declare-p usr
declare-p full
,它是否会将它们显示为包含多个不同项的数组?如果不是,我建议问一个新问题,重点是如何填充这些数组,并提供足够的详细信息来重现问题。请随意在这里添加链接;我很想看看said问题!
combine() {
  declare keys_var=$1 vals_var=$2 result_var=$3
  declare indirect i keys
  declare -gA "$result_var"

  indirect="${keys_var}[@]"; keys=( "${!indirect}" )
  for (( i=0; i < ${#keys[@]}; i++ )); do
    indirect="${vals_var}[$i]"; declare -g "${result_var}[${keys[i]}]=${!indirect}"
  done
}