当前位置 博文首页 > RtxTitanV的博客:Shell编程之数组
本文主要对Shell中的数组进行简单总结,另外本文所使用的Linux环境为CentOS Linux release 8.1.1911
,所使用的Shell为bash 4.4.19(1)-release
。
Shell支持数组,即一组数据的集合,里面的每个数据被称为一个数组元素。当前Bash仅支持一维索引数组和关联数组,对数组的长度(元素个数)没有限制,也没有对索引和成员分配要连续的要求。使用内置命令declare
可以显示声明一个数组:
# 显式声明一个数组,name表示数组名
declare -a name
# 这种语法下标会被忽略
declare -a name[subscript]
任何变量都可以用作索引数组,索引数组使用整数(包括算术表达式)进行引用(reference),并且索引从0开始,除非另有说明,索引数组索引必须是非负整数。
使用以下语法给任意变量赋值会自动创建一个索引数组:
# 会自动创建一个索引数组,数组名为name,下标被视为一个算术表达式,其结果必须为数字
name[subscript]=value
示例如下:
使用以下复合赋值语句可以定义数组并赋值:
# 对于索引数组,下标([subscript1]=)是可选的,如果指定了下标,则赋值给指定下标的元素
# 否则要赋值元素的下标是该语句所赋值的最后一个下标加1,下标从0开始
name=([subscript1]=value1 [subscript2]=value2 … )
使用复合赋值语句不指定下标的定义索引数组的示例如下:
数组元素的类型可以不同。
先定义一个列表形式的字符串,然后在()
中引用该字符串也可以定义数组,示例如下:
使用复合赋值语句指定下标的定义索引数组的示例如下:
上例只给3个指定下标的元素赋值,所以数组长度为3。
${name[*]}
获取数组所有元素,${#name[*]}
获取数组长度。
关联数组使用任意字符串来访问元素。关联数组用下面的形式来创建:
# 声明一个关联数组(必须先声明为关联数组)
declare -A name
# 可以使用单独给各个元素赋值的方式创建关联数组
name[subscript]=value
# 或者使用复合赋值语句创建数组并赋值
# 对于关联数组,下标是必须的,使用键值对时,键不能缺失和为空,最后的缺失值被视为空字符串
name=([subscript1]=value1 [subscript2]=value2 … )
# 也可以在声明的同时给数组赋值
declare -A name[subscript]=value
declare -A name=([subscript1]=value1 [subscript2]=value2 … )
使用单独给各个元素赋值的方式创建关联数组的示例如下:
使用复合赋值语句定义关联数组的示例如下:
在声明关联数组的同时给数组赋值的示例如下:
内部命令
declare
、local
和readonly
都接受-a
选项来指定索引数组,以及一个-A
选项来指定关联数组。如果两个选项都有,则优先使用-A
。内部命令read
程序接受一个-a
选项,将从标准输入中读取一组单词分配给数组,并且可以从标准输入读取值后赋给单个数组元素。内置命令set
和declare
可以以允许将数组值作为输入重用的方式显示数组值。
获取数组中单个元素的值的语法如下:
# 获取名为name的数组下标为subscript的元素的值,对于索引数组,下标大于等于0
# 对于索引数组,如果下标小于0,则索引从数组末尾开始计数,索引-1引用最后一个元素
# 如果省略下标,则获取下标为0的元素
${name[subscript]}
获取索引数组中单个元素的值的示例如下:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
# 输出数组中下标为0的元素的值
echo ${array[0]}
# 引用不带下标的数组变量等效于使用下标0的引用,也是输出数组中下标为0的元素的值
echo ${array}
# 输出数组中下标为2的元素的值
echo ${array[2]}
# 输出数组中最后1个元素的值
echo ${array[-1]}
# 输出数组中倒数第3个元素的值
echo ${array[-3]}
执行结果:
获取关联数组中单个元素的值的示例如下:
#!/bin/bash
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
# 输出数组中下标为uid的元素的值
echo ${account["uid"]}
# 输出数组中下标为username的元素的值
echo ${account["username"]}
# 输出数组中下标为email的元素的值
echo ${account["email"]}
执行结果:
使用有效下标对变量的任何引用都是合法的,并且bash会在必要时创建一个数组。如果已为下标分配了值,则认为已设置数组变量。
获取数组中所有元素的值的语法如下:
# 都是获取名为name的数组中所有元素的值,如果数组中没有元素,则结果为空
# 只有在被双引号包围时,*和@才有所不同
# 被双引号包围时,${name[*]}扩展为一个单词,每个数组元素的值都由IFS的第一个字符分隔(一般是空格),而${name[@]}仍将数组中每个元素的值都扩展为独立的单词
${name[*]}
${name[@]}
获取索引数组中所有元素的值的示例如下:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
# 使用${name[*]}语法输出数组中所有元素的值
echo ${array[*]}
# 使用${name[@]}语法输出数组中所有元素的值
echo ${array[@]}
执行结果:
获取关联数组中所有元素的值的示例如下:
#!/bin/bash
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
# 使用${name[*]}语法输出数组中所有元素的值
echo ${account[*]}
# 使用${name[@]}语法输出数组中所有元素的值
echo ${account[@]}
执行结果:
以下示例可以看出${name[*]}
和${name[@]}
的区别:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
echo "循环打印\${array[*]}中的每个元素"
for var in ${array[*]}
do
echo ${var}
done
echo "循环打印\${array[@]}中的每个元素"
for var in ${array[@]}
do
echo ${var}
done
echo "循环打印\"\${array[*]}\"中的每个元素"
for var in "${array[*]}"
do
echo ${var}
done
echo "循环打印\"\${array[@]}\"中的每个元素"
for var in "${array[@]}"
do
echo ${var}
done
执行结果:
获取数组中所有元素的下标(索引)的语法如下:
# 获取名为name的数组中所有元素的下标,双引号中的处理与特殊参数*和@类似
# 所以${!name[*]}和${!name[@]}的区别与上面的${name[*]}和${name[@]}的区别类似
${!name[*]}
${!name[@]}
获取索引数组中所有元素的下标的示例如下:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
# 使用${!name[*]}语法输出数组中所有元素的下标
echo ${!array[*]}
# 使用${!name[@]}语法输出数组中所有元素的下标
echo ${!array[@]}
执行结果:
获取关联数组中所有元素的下标的示例如下:
#!/bin/bash
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
# 使用${!name[*]}语法输出数组中所有元素的下标
echo ${!account[*]}
# 使用${!name[@]}语法输出数组中所有元素的下标
echo ${!account[@]}
执行结果:
获取数组长度的语法如下:
# 获取名为name的数组的长度(数组中元素个数)
${#name[*]}
${#name[@]}
获取数组长度的示例如下:
#!/bin/bash
# 获取索引数组长度示例
array=("hello" "shell" 123 "java" "abc" 321)
# 使用${#name[*]}语法输出数组长度
echo ${#array[*]}
# 使用${#name[@]}语法输出数组长度
echo ${#array[@]}
# 获取关联数组长度示例
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
# 使用${#name[*]}语法输出数组长度
echo ${#account[*]}
# 使用${#name[@]}语法输出数组长度
echo ${#account[@]}
执行结果:
获取数组中指定元素的长度的语法如下:
# ${#name[subscript]}会扩展为${name[subscript]}的长度,即名为name的数组中指定元素的长度(字符个数)
# 如果没有指定下标,则相当于指定了0作为下标
${#name[subscript]}
获取索引数组中指定元素的长度的示例如下:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
# 输出数组中下标为0的元素的长度
echo ${#array[0]}
# 没有指定下标,则相当于指定了0作为下标,也是输出数组中下标为0的元素的长度
echo ${#array}
# 输出数组中下标为2的元素的长度
echo ${#array[2]}
# 输出数组中最后1个元素的长度
echo ${#array[-1]}
# 输出数组中倒数第3个元素的长度
echo ${#array[-3]}
执行结果:
获取关联数组中指定元素的长度的示例如下:
#!/bin/bash
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
# 输出数组中下标为uid的元素的长度
echo ${#account["uid"]}
# 输出数组中下标为username的元素的长度
echo ${#account["username"]}
# 输出数组中下标为email的元素的长度
echo ${#account["email"]}
执行结果:
可以使用单独给元素赋值的方式来修改数组中指定元素的值:
# 通过给单个元素赋值的方式来修改数组中指定元素的值
# 指定的下标不存在会添加元素
name[subscript]=value
修改索引数组中指定元素的值的示例如下:
#!/bin/bash
array=("hello" "shell" 123 "java" "abc" 321)
echo ${array[*]}
# 修改数组中下标为0的元素的值
array[0]="world"
echo ${array[*]}
# 没有指定下标,则相当于指定了0作为下标,也是修改数组中下标为0的元素的值
array="hello"
echo ${array[*]}
# 修改数组中下标为2的元素的值
array[2]=111
echo ${array[*]}
# 修改数组中最后1个元素的值
array[-1]=333
echo ${array[*]}
# 修改数组中倒数第3个元素的值
array[-3]="c++"
echo ${array[*]}
执行结果:
修改关联引数组中指定元素的值的示例:
#!/bin/bash
declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"