循环枚举每个其他数组元素

循环枚举每个其他数组元素

我有一个带有密钥对值的动态数组,我想枚举所有其他值。在本例中,只是数组中的名称。由于我没有使用 bash v4,因此我能够使用seqecho 来遍历数组。

$ array=(Guido yes Francesca no Balthazar yes)
for x in $(seq 0 2 ${#array[@]});do echo $x;done
0
2
4
6

这将返回比我拥有的对多一个的元素(由于偏移量为 0),但我可以使用简单的 bash 数学来解释这一点:

for x in $(seq 0 2 $((${#array[@]}-1)));do echo $x;done
0
2
4

这很好用。但是当我尝试从 中提取元素时$array,我得到了一个无法解释的错误。我尝试过使用和不使用“数学”

$ for x in $(seq 0 2 $((${#array[@]}-1)));do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

$ for x in $(seq 0 2 ${#array[@]});do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

我怎样才能从这个动态数组中获取名称?

编辑:$BASH_VERSION的是3.2.57(1)-releaseMac OS X 10.10.2

编辑#2:我得出的结论是,这可能是此版本中的一个错误。由于我管理着许多 AWS 实例,因此我决定检查它们,它们都安装了 bash 4.1.2(1)。我将我的 Mac 升级到此版本,现在可以正常工作了。感谢您的关注,但我认为这是异常现象。

答案1

如果想要循环遍历数组的交替元素,这个应该在 bash 3.2 上运行:

while IFS= read -d '' -r name; do
  # do something with "$name"
done < <(printf %s%.0s\\0 "${array[@]}")

xargs -0如果更方便的话,您可以做类似的事情。

如果您的名字中都不包含冒号(例如),您可以将名字提取到新数组中,如下所示:

IFS=: read -a names -r < <(printf %s%.0s: "${array[@]}")

(不幸的是,您不能将字段分隔符设置为 NUL。)

所有这些都依赖于这样一个事实:printf重复其格式字符串的频率要尽可能高,以使用其所有参数(Posix 行为,因此它应该适用于任何 bash 版本,或非内置版本printf)。偶尔有用的格式%.0s使用一个参数并从中打印最多 0 个字符,也就是说将其放入 bitbucket 中。

相关内容