欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

Bash脚本编程之数组

程序员文章站 2023-08-30 16:59:21
数组简介 在bash脚本编程当中,变量是存储单个元素的内存空间;而数组是存储多个元素的一段连续的内存空间。 数组由数组名和下标构成,如下。 ARRAY_NAME[SUBSCRIPT] 数组按照下标的类型可分为两种: 索引(indexed)数组:下标为0、1、2等非负整数。 关联(associativ ......

数组简介

在bash脚本编程当中,变量是存储单个元素的内存空间;而数组是存储多个元素的一段连续的内存空间。

数组由数组名和下标构成,如下。

array_name[subscript]

数组按照下标的类型可分为两种:

  • 索引(indexed)数组:下标为0、1、2等非负整数。
  • 关联(associative)数组:下标为用户自定义的字符串。

 

数组的操作

声明

索引数组可以不声明直接使用;而关联数组如果不声明直接使用的话,会被认为是索引数组,即使它的下标是字符串。

索引数组的声明方式。

# declare -a array_name

关联数组的声明方式。

# declare -a array_name

赋值

一次只赋值一个元素。

# array_name[subscript]=value

一次赋值全部元素。

# array_name = ("val1" "val2" "val3" ...)

一次赋值多个可以是不连续的元素。

# array_name = ([0] = "val1" [3] = "val3")

像这种不要求元素必须依次存在的数组(即可以在没有a[1]和a[2]的时候就赋值a[3]),叫做稀疏格式数组。因此,bash支持稀疏格式的数组。

读取标准输入赋值数组。

# read -a array_name

在输入的时候,以空格作为元素的分隔符,以回车键结束元素的赋值。

向数组的末尾追加元素。

array_name[${#array_name[@]}]=value 

或者

array_name+=(value)

引用

引用单个数组元素。

${array_name[subscript]}

如果省略subscript,那么就等同于subscript=0。即以下两个引用是相同的。

${array_name[0]}
${array_name}

引用数组的所有元素。正常情况下,二者没有区别,只有当被双引号包裹的时候,“@”被展开为每个元素为一个独立的单词;“*”被展开为所有元素为一个统一的单词。

${array_name[@]}
${array_name[*]}

引用数组元素的长度。

${#array_name[subscript]}

引用数组的长度,即数组的元素个数。

${#array_name[@]}
${#array_name[*]}

引用数组的部分元素(切片)。

${array_name[@]:offset:number}
${array_name[*]:offset:number}

offset:偏移,表示偏移/跳过数组中的前几个元素。

number:表示偏移后取几个元素。

如果省略了number,并且offset的值为“ -n”(注意,-n的左边有空格),则表示引用倒数的几个元素。

截止目前我们引用的都是数组的值,如果我们想引用数组的下标的话,可以使用:

${!array_name[@]}
${!array_name[*]}

删除

删除数组元素。

# unset array_name[subscript]

删除数组。

# unset array_name

 

数组示例

定义一个索引数组,逐一赋值数组元素。

[root@c7-server ~]# declare -a my_array
[root@c7-server ~]# my_array[0]=zhang
[root@c7-server ~]# my_array[1]=wen
[root@c7-server ~]# my_array[2]=long

根据数组下标获取数组元素。留意我们上文说的,当引用数组不带下标的时候,等同于引用${array_name[0]}。

[root@c7-server ~]# echo ${my_array}
zhang
[root@c7-server ~]# echo ${my_array[0]}
zhang
[root@c7-server ~]# echo ${my_array[1]}
wen
[root@c7-server ~]# echo ${my_array[2]}

引用数组中的所有元素,顺便测试一下“@”和“*”的区别。注意,这个区别,仅在${my_array[@]}或者${my_array[*]}被双引号包裹的情况下才会出现。

[root@c7-server ~]# echo ${my_array[@]}
zhang wen long
[root@c7-server ~]# echo ${my_array[*]}
zhang wen long
[root@c7-server ~]# for i in "${my_array[@]}"; do echo $i; done
zhang
wen
long
[root@c7-server ~]# for i in "${my_array[*]}"; do echo $i; done
zhang wen long

引用数组个数。

[root@c7-server ~]# echo ${#my_array[@]}
3
[root@c7-server ~]# echo ${#my_array[*]}
3

引用数组中元素的个数。

[root@c7-server ~]# echo ${my_array[0]}
zhang
[root@c7-server ~]# echo ${#my_array[0]}
5

接下来演示其他几种不同的赋值方式,操作前可先删除数组。

[root@c7-server ~]# unset my_array
[root@c7-server ~]# my_array=([0]=zhang [1]=wen [2]=long)
[root@c7-server ~]# echo ${my_array[@]}
zhang wen long
[root@c7-server ~]# unset my_array
[root@c7-server ~]# read -a my_array
mon tue wed thu fri sat sun
[root@c7-server ~]# echo ${my_array[@]}
mon tue wed thu fri sat sun

数组元素去子串(substring),即切片。

[root@c7-server ~]# echo ${my_array[@]}
mon tue wed thu fri sat sun
[root@c7-server ~]# echo ${my_array[@]:3:2}
thu fri
[root@c7-server ~]# echo ${my_array[@]:2:3}
wed thu fri
[root@c7-server ~]# echo ${my_array[@]: -3}
fri sat sun

数组元素追加。

[root@c7-server ~]# echo ${my_array[@]}
mon tue wed thu fri sat sun
[root@c7-server ~]# my_array+=(ddd)
[root@c7-server ~]# my_array[${#my_array[@]}]=eee
[root@c7-server ~]# echo ${my_array[@]}
mon tue wed thu fri sat sun ddd eee

引用数组的下标(subscript)。个人感觉引用数组下标在关联数组中比较有用,在索引数组中用处不大。

[root@c7-server ~]# echo ${!my_array[@]}
0 1 2 3 4 5 6 7 8
[root@c7-server ~]# unset my_array
[root@c7-server ~]# declare -a my_array
[root@c7-server ~]# my_array=([name]=zwl [age]=28 [sex]=male)
[root@c7-server ~]# echo ${my_array[@]}
zwl 28 male
[root@c7-server ~]# echo ${!my_array[@]}
name age sex