Bash数组和负下标,是还是不是?

21

根据GNU bash手册,告诉我

An indexed array is created automatically if any variable is assigned to using the syntax

name[subscript]=value

The subscript is treated as an arithmetic expression that must evaluate to a number. If subscript evaluates to a number less than zero, it is used as an offset from one greater than the array’s maximum index (so a subcript of -1 refers to the last element of the array).

所以我觉得我可以试试并获得以下结果:
$ muh=(1 4 'a' 'bleh' 2)
$ echo $muh
1
$ echo ${muh[*]}
1 4 a bleh 2    # so far so good so now I'll try a negative ...
$ echo ${muh[-1]}
-bash: muh: bad array subscript  # didn't go as planned!

我是否做错了什么,还是网站出了问题,或者gnu bash与我在CentOS下运行的bash有很大不同?谢谢!


1
它是版本特定的。在bash 4.2下工作正常,但在3.2下却失败了。 - iruvar
1
@ravoori:啊!我有3.2版本了!谢谢。 - bob.sacamento
5个回答

21

如果你只想要最后一个元素

$ echo ${muh[*]: -1}
2

如果您想要获取倒数第二个元素

$ echo ${muh[*]: -2:1}
bleh

2
@bob.sacamento 这是因为 ${parameter:-word} 是一种不同的扩展,意思是 如果 parameter 未设置或为空,则替换为 word - kojiro
3
请注意${muh[*]: -2}会给出最后两个元素,而不是倒数第二个元素。(我还没有查看手册以确定这种语法中的[deleted]来自哪里。) - Keith Thompson
2
${muh[*]: -2} 是子字符串扩展的一个例子,在数组上的作用类似于切片。 - chepner
@kojiro,请允许我向互联网上的一位陌生人发自内心地表示感谢!我从未想到需要一个空格来进行反向索引。 - Christopher King

10
根据Greg Wooledge的维基(链接到bash更改日志),负索引语法是在bash 4.2 alpha版中添加的。

7

Bash 4.2之前的版本(比如现在Mac上默认的版本)不支持负数下标。除了接受答案中使用的“子字符串扩展”外,可能更清晰的解决方法是在方括号内从数组开头计算所需索引:

$ array=(one two three)
$ echo "${array[${#array[@]}-1]}"
three

使用这种方法,您可以将其他参数扩展操作打包到术语中,例如“移除匹配前缀模式”th

$ echo "${array[${#array[@]}-1]#th}"
ree

3
如果您执行man bash,其中关于数组的部分不会列出此行为。这可能是bash中的新内容(gnu?)。在CentOS 6.3(bash 4.1.2)中对我失败。

3

在我的电脑上,使用Ubuntu 14.04 / GNU bash version 4.3.11(1),负下标完全可以正常工作。然而,它返回:

line 46: [-1]: bad array subscript

当我尝试在版本号为4.2.46(1)的环境中执行相同的脚本时,出现了问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接