6.7 数组

评论 0 浏览 0 2023-01-26

Bash提供了一维的索引数组和关联数组变量。任何变量都可以作为索引数组使用; declare内置命令会明确声明一个数组。对数组的大小没有最大的限制,也没有要求成员必须是索引或连续分配的。索引数组使用整数(包括算术表达式(见6.5 shell算术))进行引用,并且是基于零的;关联数组使用任意的字符串。 除非另有说明,索引数组的索引必须是非负整数。

如果使用以下语法分配了任何变量,则会自动创建索引数组。

name[subscript]=value

下标被视为必须求值为数字的算术表达式。 要显式声明一个数组,请使用

declare -a name

语法

declare -a name[subscript]

也被接受;下标被忽略。

关联数组的创建方法是使用

declare -A name

可以使用declarereadonly内置函数为一个数组变量指定属性。每个属性都适用于一个数组的所有成员。

数组的赋值是使用复合赋值,其形式为

name=(value1 value2 … )

其中每个value可能是[subscript]=string的形式。 索引数组的赋值除了string之外不需要任何东西。 当赋值到索引数组时,如果提供了可选的下标,则赋值到该索引;否则赋值到的元素的索引是语句所赋值的最后一个索引加上1。索引从零开始。

列表中的每个value都经历了上述所有的shell扩展(见3.5 Shell的扩展)。

当向关联数组赋值时,复合赋值中的词可以是赋值语句,需要下标,或者是一个词的列表,被解释为键和值的交替序列: name=(key1 value1 key2 value2 …) 。这些与name=( [key1]=value1 [key2]=value2 …)的处理方式相同。 列表中的第一个词决定了其余词的解释方式;列表中的所有赋值必须是同一类型。 使用键/值对时,键不得缺少或空;最后缺少的值被当作空字符串处理。

这种语法也被declare内置程序所接受。单个数组元素可以使用上面介绍的name[subscript]=value语法进行分配。

当赋值给一个有索引的数组时,如果name的下标是一个负数,那么这个数字会被解释为相对于比name的最大索引大一个,所以负数的索引从数组的末端开始往回数,而索引为-1则是引用最后一个元素。

当使用复合赋值语法进行赋值时,‘+=’操作符将追加到数组变量中;见上面的3.4 shell参数

可以使用${name[subscript]} 引用数组的任何元素。需要大括号以避免与 shell 的文件名扩展运算符发生冲突。如果下标为‘@’或‘*’,则单词扩展为数组名称的所有成员。只有当单词出现在双引号内时,这些下标才会不同。 如果单词被双引号括起来,${name[*]}扩展为单个单词,每个数组成员的值由IFS变量的第一个字符分隔,${name[@]}扩展name的每个元素 到一个单独的词。当没有数组成员时,${name[@]} 展开为空。如果双引号扩展出现在一个单词中,则第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。这类似于特殊参数“@”和“*”的扩展。${#name[subscript]} 扩展到${name[subscript]}的长度。如果 下标 是‘@’或者 ‘*’,扩展为数组元素个数。如果用于引用索引数组元素的下标 的计算结果为小于零的数字,则它被解释为相对于大于数组最大索引的一个,因此负索引从数组的末尾开始计数,并且 -1 的索引指的是最后一个元素。

引用一个没有下标的数组变量相当于用下标0来引用。任何使用有效下标的变量引用都是合法的,如果有必要的话,bash会创建一个数组。

如果一个数组变量的下标已经被分配了一个值,那么这个数组变量就被认为是被设置了。空字符串是一个有效的值。

可以获得数组的键(索引)以及值。${!name[@]}和${!name[*]}扩展到数组变量name中分配的索引。 在双引号中的处理与特殊参数‘@’和‘*’在双引号中扩展的情况相似。

内置函数unset是用来销毁数组的. unset name[subscript]是销毁索引下标的数组元素。索引数组的负下标按上述解析。取消数组变量的最后一个元素不会取消该变量。unset name,其中name是一个数组,删除整个数组。当给定一个‘*’或‘@’的下标时,unset name[subscript]的行为会因数组类型而有所不同。当name是一个关联数组时,它会删除键值为‘*’或‘@’的元素。 如果name是一个索引数组,unset会删除所有的元素,但不会删除该数组本身。

当使用带有下标的变量名作为命令的参数时,例如使用unset,而不使用上面描述的单词扩展语法时,该参数会受到shell文件名扩展的影响。 如果不需要文件名扩展,该参数应该被引号化。

declare, local, 和 readonly 内置程序分别接受 -a 选项来指定一个索引数组,以及 -A 选项来指定一个关联数组。 如果两个选项都提供,-A 优先。 read 内置程序接受 -a 选项来指定一个从标准输入读取的单词列表到数组,并且可以从标准输入读取数值到单个数组元素。setdeclare 内置程序显示数组值的方式允许它们作为输入被重复使用。

最后更新2023-02-20
0 个评论
上一篇: 6.6 别名
下一篇: 6.8 目录堆栈
当前页面书签