访问bash数组的倒数第二个元素



我可以访问数组的所有元素,如下所示:

echo ${myarray[@]}

元素数量:

echo ${#myarray[@]}

我可以通过做得到第n个元素:

echo ${myarray[@]:(-1)}

然而,我尝试以下操作来获得第n-1个数组元素:

echo ${myarray[@]:(-2)}

但我最后提到了最后两个元素。如何只获得倒数第二个元素?

您可以添加另一个冒号,并指定切片的长度:

echo "${myarray[@]: -2: 1}"

例如(尽管我很惭愧在这台机器上展示我的老式bash版本…):

$ echo "$BASH_VERSION"
3.1.20(4)-release
$ a=( 1 2 3 )
$ echo ${a[@]: -2: 1}
2

您还可以在标准数组引用的索引部分进行计算:

$ myarray=( {0..100} )
$ echo "${myarray[ ${#myarray[@]} - 2 ]}"
99

或者,更清楚一点:

$ myarray=( {0..100} )
$ myarray_len="${#myarray[@]}"
$ echo "${myarray[ myarray_len - 2 ]}"
99

顺便说一句,请养成双重引用所有变量引用的习惯(例如echo "${myarray[@]}"而不是echo ${myarray[@]})。在某些情况下,省略引号是安全的,但在很多情况下也不安全,弄清楚什么时候可以安全地省略引号是一项艰巨的工作。只要引用所有的,除非有特定的原因不这样做。

我的bash版本似乎直接支持负索引:

$ echo $BASH_VERSION
4.3.33(1)-release
$ x=( {0..100} )
$ echo "${x[-45]}"
56

该功能已添加到bash-4.3阿尔法中。请参阅更改日志,4.3阿尔法下的3x部分。

编辑:关于负指数的观察

我在Gordon Davisson的回答中评论说,如果减法器比数组大,你会得到一个错误。Bash 4.3中的负指数似乎也是如此:

$ myarray=( {0..100} )
$ echo "${myarray[-104]}"
-bash: myarray: bad array subscript

这与任何正索引都有效的普通bash稀疏数组不一致。它可能不是设置,但没有错误:

$ echo "${myarray[500]}"
(no output)

另一方面,负切片不受此影响:

$ echo "${myarray[@]: -500:1}"
(no output; no error)

摘要

  • slice方法在旧的bash中得到支持,并且不受溢出错误的影响,但读写起来很麻烦
  • 负索引方法读写起来很简单,但只有在最新的bash版本中才支持,如果索引太负,可能会出错
  • 计算索引方法读取起来仍然相当简单,并且可以在旧的bash版本中使用,但如果负值太大,则可能会出错或给出意外的答案

最新更新