【问题标题】:Modify an Array Function Parameter Bash修改数组函数参数 Bash
【发布时间】:2015-03-29 04:38:31
【问题描述】:

我正在尝试修改作为参数传递给函数的数组。到目前为止,我在函数之外有一个空数组:

buckets=()

然后我有一个接受 2 个参数的函数。第一个参数是我要填充的空数组。第二个参数是包含我要用来填充数组的数据的文件的名称。

到目前为止,我所做的是创建一个临时数组。然后用文件的内容填充临时数组。我就是这样做的:

fillarray ()
{
# Declare the paramater as a temporary array
declare -a tempArray=("${!1}")

# Fill it up
while IFS= read -r entry; do
  tempArray+=("$entry")
done < <(jq -r '.data | .[].name' $2)

最后一步是将参数数组(又名存储桶)设置为我们刚刚填充的临时数组的内容。有关如何执行此操作的任何建议?

【问题讨论】:

  • 如果你的 tempArray 有你需要的东西,那么将它复制到 buckets 数组会很容易,例如: Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Linux=("${Unix[@]}");回声 ${Linux[@]};有关更多操作,请参阅此内容:thegeekstuff.com/2010/06/bash-array-tutorial ---或查看此内容以将数组复制到另一个 stackoverflow.com/questions/19417015/…
  • @ArunSangal 如果我有并且知道变量名,你给出的例子就可以工作。我的问题是函数内部的泛型参数会修改函数外部的变量。我正在尝试重构我的代码,这样我就不必重复自己了。这就是为什么我试图将这个 fillarray 捕获为一个函数并传入我想要填充的数组。谢谢你的教程。我将阅读它们以更加熟悉 bash。

标签: arrays bash parameters jq


【解决方案1】:

另一种方式通过eval

fillarray () {
 local tempArray;

 while IFS= read -r entry; do
    tempArray[${#tempArray[@]}]="$entry";
 done < <(jq -r '.data | .[].name' $2);

 eval $1=\('"${tempArray[@]}"'\);
}

【讨论】:

  • 当我做了一些研究时,我发现这是一个可能的解决方案。许多人声称它有效,但我真的不明白如何。 eval 做了什么让它如此...特别?我还读到这可能会导致一些安全问题?我不知道怎么做,但如果我能理解 eval 在做什么,那么我可以看到安全性可能是一个问题。 bash 很奇怪。
  • 如果 $1 包含,例如,“buckets”; eval 代码等价于buckets=(${tempArray[@]}),即 tempArray 被复制到 buckets 数组中。
【解决方案2】:

BASH 4.3+ 中,您可以通过命名引用传递一个数组。所以你的功能可以简化为:

fillarray() {
   # tempArray is a reference to array name in $1
   local -n tempArray="$1"
   while IFS= read -r entry; do
      tempArray+=("$entry")
   done < <(jq -r '.data | .[].name' "$2")
}

然后称它为:

buckets=()
fillarray buckets file.json

并将其测试为:

declare -p buckets

编辑:要使其在 BASH 3.2 上运行,请使用以下 sn-p:

fillarray() {
   # $2 is current length of the array
   i=$2
   while IFS= read -r entry; do
      read ${1}"[$i]" <<< "$entry"
      ((i++))
   done < <(jq -r '.data | .[].name' "$3")
}

然后称它为:

buckets=()
fillarray buckets ${#buckets[@]} file.json

【讨论】:

  • 这行得通。澄清一下,你认为你能解释一下&lt;&lt;&lt;i++ 周围的双括号是什么意思吗?还有为什么我们在增加它时不必在i 之前放置$
  • ((i++)) 是 BASH 算法,用于递增 i&lt;&lt;&lt; 在 BASH 中被称为此处字符串,以将 $entry 提供给 ${1}"[$i]",其中 ${1} 是数组的名称,@ 987654336@是读取命令中的数组索引
猜你喜欢
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多