13.1.7 数组

数组是一种特殊的数据结构,其中的每一项被称为一个元素,对于每个元素,都可以用索引方式取出元素的值。使用数组的典型场景是一次性要记录很多类型相同的数据时(但不是说一定要相同,因为Shell变量是弱类型性的,并不要求数组的每个元素都是相同类型)。比如,为了记录班级中所有人的数学成绩,如果不用数组来处理那就只能定义所有人成绩的变量,这就会显得非常烦琐。Shell中的数组对元素个数没有限制,但只支持一维数组,这一点和很多语言不同。

1.数组定义

数组的定义方法如下:用declare命令定义数组Array,并将第一个元素赋值为0,第二个元素赋值为1,其下标(也就是索引)则分别是0和1(记住数组的索引是从0开始计数的),然后打印出第一个元素的值。


  1. #
  2. 定义名为Array
  3. 的索引数组
  4. [root@localhost ]# declare -a Array
  5. #
  6. 数组的下标从0
  7. 开始计数,定义了第一个元素值为0
  8. ,第二个元素值为1
  9. [root@localhost ]# Array[0]=0
  10. [root@localhost ~]# Array[1]=1

如果说数组Array的前两个元素“类型相同”(严格意义上这么说是不对的),那么第三个元素就显得“另类”了:赋值为一个字符串。这又一次验证了Shell变量是弱类型的,这在很多语言中是不可能的。


  1. [root@localhost ~]# Array[2]="HelloWorld"

和其他变量一样,Shell中对于数组变量的声明也非常宽松,而且随时都可以根据需要增加变量中的元素。相比其他语言,Shell的数据更为灵活。在很多语言中,一旦对数组进行了初始化就不能再改变大小了。


  1. #
  2. 数组还可以在创建的同时赋值
  3. [root@localhost ]# declare -a Name=('john' 'sue')
  4. #
  5. 增加元素
  6. [root@localhost ]# Name[2]='wang'
  7. #
  8. 更简单的创建数组的方式——不使用declare
  9. 关键字
  10. #[root@localhost ~]# Name=('john' 'sue')

还可以给特定的元素赋值。下面的示例就是只对第四个、第六个、第八个元素进行赋值。


  1. #
  2. 跳号赋值
  3. [root@localhost ~]# Score=([3]=3 [5]=5 [7]=7)

2.数组操作

1)数组取值:知道了如何定义数组和赋值元素后,下面就要了解数组的一些常见操作。最简单的操作就是数组取值,其格式为:${数组名[索引]}。以之前定义的数组Array、Name为例,取值演示如下:


  1. #
  2. 取数组第一个元素的值
  3. [root@localhost ]# echo ${Array[0]}
  4. 0
  5. [root@localhost ]# echo ${Array[2]}
  6. HelloWorld
  7. #
  8. 打印数组中的元素值
  9. [root@localhost ]# echo ${Name[0]}
  10. john
  11. [root@localhost ]# echo ${Name[1]}
  12. sue

指定索引只能列举单个元素,要是想一次性取出所有元素的值,可以采取以下两种方式:


  1. [root@localhost ]# echo ${Array[@]}
  2. 0 1 HelloWorld
  3. [root@localhost ]# echo ${Array[*]}
  4. 0 1 HelloWorld

从表面上来看两者没有什么区别,但是${Array[@]}得到的是以空格隔开的元素值,而${Array[*]}的输出是一整个字符串。

2)数组长度:即数组元素个数。利用“@”或“*”字符,可以将数组扩展成列表,然后使用“#”来获取数组元素的个数,如下所示:


  1. [root@localhost ]# echo ${#Array[@]}
  2. 3
  3. [root@localhost ]# echo ${#Array[*]}
  4. 3

如果某个元素是字符串,还可以通过指定索引的方式获得该元素的长度,如下所示:


  1. [root@localhost ~]# echo ${#Array[2]}
  2. 10

3)数组截取:可以截取某个元素的一部分,对象可以是整个数组或某个元素。


  1. #
  2. 取出数组的第一、第二个元素
  3. [root@localhost ~]# echo ${Array[@]:1:2}
  4. 1 HelloWorld
  5. #
  6. 取出第二个元素从第0
  7. 个字符开始连续5
  8. 个字符
  9. [root@localhost ~]# echo ${Array[2]:0:5}
  10. Hello

4)连接数组:将若干个数组进行拼接操作。


  1. [root@localhost ~]# Conn=(${Array[@]} ${Name[@]})
  2. [root@localhost ~]# echo ${Conn[@]}
  3. 0 1 HelloWorld john sue

5)替换元素:将数组内某个元素的值替换成其他值。


  1. [root@localhost ~]# Array=(${Array[@]/HelloWorld/HelloJohn})
  2. [root@localhost ~]# echo ${Array[@]}
  3. 0 1 HelloJohn

6)取消数组或元素:和取消一般变量一样,取消一个数组的方式也使用unset命令。


  1. #
  2. 取消数组中的一个元素
  3. [root@localhost ~]# unset Array[1]
  4. [root@localhost ]# echo ${Array[@]}
  5. 0 HelloJohn
  6. #
  7. 取消整个数组
  8. [root@localhost ]# unset Array
  9. [root@localhost ]# echo ${Array[@]}
  10. #
  11. 本行打印为空,说明Array
  12. 已经被取消了
  13. [root@localhost ]#