为什么bash
似乎计算数组中的单词而不是元素的数量?
touch '1 red' '2 orange' '3 yellow' # Three filenames, each of two words
files=( * ) # Get the set of files
echo "#files is ${#files}"
for (( i=0; i <= ${#files}; i++ ))
do
printf "%d\t%s\n" $i "${files[$i]}"
done
这个输出似乎是“错误的”。对于初学者来说,${#files}
contains 5
,表明 中有六个元素${files[@]}
。但是,只有元素0
、1
和2
of${files[@]}
包含任何数据,并且它们包含正确的文件名:
#files is 5
0 1 red
1 2 orange
2 3 yellow
3
4
5
我本来期望要么${files[@]}
包含六个单词1
, red
, 2
, orange
, 3
, and yellow
, 要么${#files}
包含2
。不是这种混合场景。
有人可以帮我解释一下吗?
答案1
${#files}
是数组第一个元素的长度,即 的长度1 red
。也就是五个。
来自手动的:
${#name[subscript]} 扩展为 ${name[subscript]} 的长度。如果下标为“@”或“*”,则扩展为数组中元素的数量。 [...]
引用不带下标的数组变量相当于引用下标为 0 的数组变量。
所以,${#files}
= ${#files[0]}
。但是${#files[@]}
或者${#files[*]}
给出数组中元素的数量。
(它与单词数无关,但如果${files[*]}
不加引号进行扩展,则会对所有值进行通常的单词分割。)
答案2
请更改${#files}"
为${#files[@]}"
您将得到 5,${#files}"
因为这是第一个文件。
相当于${files[0]}
,被命名为“1 red”。
那细绳包含 5 个字符。
对于同样的问题,循环失败,它从 1 迭代到 5。
但是,元素 3、4 和 5 只是 null(未设置)。