如何使用 descriptive/readable 语句获取 BASH 数组长度?

How to get BASH array length with descriptive/readable statement?

似乎在 BASH 中获取数组长度的标准方法是使用 ${#myArray[@]},如下所示:

myArray=( 1 3 5 7 9 )
length=${#myArray[@]}

echo "length: $length" # length: 5

尽管如此,该语法令人厌恶地晦涩难懂。有没有类似count( $myArray )myArray.length等的内置方法?

您可以轻松地实现count "${myArray[@]}",如果这会让您感觉更好:

count() { echo "$#"; }
length=$(count "${myArray[@]}")

...或者,作为不需要命令替换(以及随之而来的性能影响)来分配结果的替代方案:

assignCount() {
  local -n assignCount_arr=
  printf -v "" %s "${#assignCount_arr[@]}"
}
assignCount length myArray

但是,这并不能使语法简单明了——如果由于省略引号而被滥用,f/e,数组的内容可以被解释为 glob 表达式,或者其内容包含IFS 中的字符可能 return 不正确的值。

坦率地说,bash 不是 easy-to-use 语言,并试图将其视为 leads to numerous, severe bugs。让 "here there be dragons" 可见 up-front 比让人们自满并凭借 学习来龙去脉而留下主要错误要明智得多执行模型和语法。

我把这个答案扔掉了。请注意 eval 是一个安全漏洞,如果不仔细监控 and/or 清理数据,您可以通过它驾驶卡车炸弹。 eval 是对讽刺的轻率使用,我应该更清楚地说明这一点。 (我认为关于 Java 或 Perl 的行会说明这一点,但我想不会,哈哈)

这是一个更合理的版本,您会注意到它使用了 Charles Duffy 的解决方案几乎

lengthOf() {
  local -n standin=   # standin is a *reference* to the name passed
  echo "${#standin[@]}"
}

这与下面我原来的工作方式相同,但考虑一下典型用途 - 大多数时候,您只想保存 return,所以成语是

len=$( lengthOf someArray )

如果是这样,查看 Charles 的解决方案,因为在同一调用中直接分配变量会更好。


Original answer

如果你只想要语法糖,你将不得不涉足你喜欢的部分的杂草,并且可能会产生一些相当丑陋的安全问题,因为好吧……但是为了练习的乐趣,这里有一个选项。肯定会有人提供改进的。

lengthOf() { eval "echo ${#[@]}"; }

现在,如果你有一个声明为 a=( a b c ) 的数组,你可以这样做:

lengthOf a

它将打印 3。只是不要指望它会给你 string 的长度而不是数组....

Bash 完全是关于上下文的,所以如果一点语法上的努力困扰你,也许你应该尝试另一种语言......比如 Java,或者 Perl,哈哈! ;)