将 bash 数组复制到名称由另一个变量保存的变量

将 bash 数组复制到名称由另一个变量保存的变量

有很多类似的问题,但我不明白任何答案作为以下问题的解决方案:

我想创建一个包含两个参数的 bash 函数,第一个是变量名,第二个是搜索字符串(用于文件搜索)。

因此,我希望变量名称保存找到的文件的数组。

我有一个包含以下文件的目录:

  • .jpg
  • b.tif
  • c.jpg

该函数定义为:

search-files--fill-array()
{
    local variable_name="${1}"
    declare -a eval ${variable_name}

    local search_string="${2}"
    echo "${search_string}"

    local nullglob_setting=$(shopt -p nullglob)
    shopt -s nullglob
    found_files=(${search_string})
    eval "${nullglob_setting}"

    eval ${variable_name}=(${found_files[@]})
}

但最后一行会导致语法错误。它应该将数组分配给作为函数第一个参数提供的变量,因此调用该函数:

search-files--fill-array my_variable_a "*.jpg"

所以想要的结果应该是

echo "${my_variable_a[@]}"

显示两个文件“a.jpg”和“c.jpg”作为数组,即

echo "${#my_variable_a[@]}"

结果应为“2”。

如果它不必是数组,解决方案是使用以下最后一行:

eval ${variable_name}=\${found_files}

没有任何成功,我还尝试使用 while 循环从旧数组形成新数组,但这也不起作用。

eval ${variable_name}="\${found_files[@]}"

生成my_variable_a包含字符串但不包含数组的结果。

背景

也许我的做法是完全错误的。

为了明确起见:我想用一个数组填充一些变量,每个变量保存通过通配符找到的文件的文件名(对于不同的搜索“字符串”总是以相同的方式)。我只期望文件,而不考虑子目录,并且我必须确保结果始终可靠地排序。)

我想避免冗余代码。

shopt部分是必要的,以确保如果当前目录中不存在文件,则数组将填充零个条目,而如果没有 nullglob,则将有一个条目包含搜索“string”的内容。

解决方案

作为比利叔叔建议,我可以declare -n var在这里使用。

工作功能:

search-files--fill-array()
{
    declare -n function=$1
    local shopt_setting=$BASHOPTS
    shopt -s nullglob
    function=($2)
    [[ :$shopt_setting: = *:nullglob:* ]] || shopt -u nullglob
}

他提议的重置处理会nullglob导致该函数不再包含任何函数eval。你可以阅读例如这个堆栈交换帖子了解为什么避免eval值得考虑。

答案1

使用变量引用:

search-files--fill-array()
{
  typeset -n a=$1
  local s=$BASHOPTS
  shopt -s nullglob
  a=($2)
  [[ :$s: = *:nullglob:* ]] || shopt -u nullglob
}

prompt> touch foo.txt bar.txt
prompt> search-files--fill-array foo '*.txt'
prompt> typeset -p foo
declare -a foo=([0]="bar.txt" [1]="foo.txt")

help declare了解更多详细信息(declare是 的同义词typeset)。


declare -a eval ${variable_name}

这将声明两个数组当地的对于该函数,一个命名为eval,另一个命名为 的内容${variable_name}。无论你给它们赋值什么,函数返回后它都会丢失。用于declare -g使它们全球化。

eval ${variable_name}=(${found_files[@]})=> 语法错误

echo foo=(bar)与=> 语法错误相同。(是一个元字符,它不能在任何地方使用,只能在命令的开头(例如, after ;&&等)或作为分配给数组时使用的特殊语法的一部分。

相关内容