计算bash数组中元素的个数,其中数组的名字是动态的(即存储在一个变量中)

drw*_*ode 11 bash array parameter shell-script shell-builtin

问题的简要说明:

是否有内置的 bash 方法来计算 bash 数组中元素的数量,其中数组的名称是动态的(即存储在变量中),而无需完全复制数组或使用eval?

更多信息:

使用 bash 参数替换,可以执行以下操作:

  • 确定数组的长度:
    myArr=(A B C); echo ${#myArr[@]}.
  • 按名称间接引用变量:(
    NAME=myVar; echo ${!NAME}
    这也适用于数组元素):
    NAME=myArr[1]; echo ${!NAME}

但是如果一个数组的名称存储在另一个变量中,如何确定数组中元素的数量?(人们可能认为这是一种组合上述两个参数替换。)例如:

myArr=(A B C D)
NAME=myArr
# Get the number of elements in the array indirectly referenced by NAME.
count=${#$NAME[@]}  # This syntax is invalid. What is the right way?
Run Code Online (Sandbox Code Playgroud)

以下是所有失败的多次尝试:

  # Setup for following attempts:
  myArr=(A B C D)
  NAME=myArr
  EXPR1=$NAME[@]          # i.e. EXPR1='myArr[@]'
  EXPR2=#$NAME[@]         # i.e. EXPR2='#myArr[@]'

  # Failed attempts to get the lengh of the array indirectly:
  1.  count=${#$NAME[@]}  # ERROR: bash: ...: bad substitution
  2.  count=${#!EXPR1}    # ERROR: bash: !EXPR}: event not found
  3.  count=${#\!EXPR1}   # ERROR: bash: ...: bad substitution
  4.  count=${!#EXPR1}    # ERROR: bash: ...: bad substitution
  5.  count=${!EXPR2}     # Returns NULL
Run Code Online (Sandbox Code Playgroud)

我还尝试了上述的一些其他变体,但还没有找到任何可以工作的东西:(A)制作数组的副本或(B)使用eval.

工作方法:

有几种解决这个问题的方法可能不是最佳的(但如果我错了,请纠正我):

方法一:复制数组

将数组分配给另一个(静态命名的)变量并获取其中的元素数。

EXPR=$NAME[@]
arrCopy=( "${!EXPR}" )
count=${#arrCopy}
Run Code Online (Sandbox Code Playgroud)

方法二:使用 eval

EXPR="count=\${#$NAME[@]}"  # i.e. 'count=${myArr[@]}'
eval $EXPR
# Now count is set to the length of the array
Run Code Online (Sandbox Code Playgroud)

概括:

bash中是否有任何内置方法(即参数替换语法)来间接确定数组的长度?如果不是,那么最有效的方法是什么?我认为这是eval上面的方法,但是是否存在安全或性能问题eval

gle*_*man 0

bash 4.3 namerefs 是天赐之物。但是,您可以这样做:

$ myArr=(A B C D)
$ NAME=myArr
$ tmp="${NAME}[@]"
$ copy=( "${!tmp}" )
$ echo "${#copy[@]}"
4
Run Code Online (Sandbox Code Playgroud)