当前位置 博文首页 > RtxTitanV的博客:Shell编程之数组

    RtxTitanV的博客:Shell编程之数组

    作者:[db:作者] 时间:2021-07-07 10:02

    本文主要对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]
    

    1.定义索引数组

    任何变量都可以用作索引数组,索引数组使用整数(包括算术表达式)进行引用(reference),并且索引从0开始,除非另有说明,索引数组索引必须是非负整数。

    使用以下语法给任意变量赋值会自动创建一个索引数组:

    # 会自动创建一个索引数组,数组名为name,下标被视为一个算术表达式,其结果必须为数字
    name[subscript]=value
    

    示例如下:
    1
    使用以下复合赋值语句可以定义数组并赋值:

    # 对于索引数组,下标([subscript1]=)是可选的,如果指定了下标,则赋值给指定下标的元素
    # 否则要赋值元素的下标是该语句所赋值的最后一个下标加1,下标从0开始
    name=([subscript1]=value1 [subscript2]=value2 … )
    

    使用复合赋值语句不指定下标的定义索引数组的示例如下:
    2

    数组元素的类型可以不同。

    先定义一个列表形式的字符串,然后在()中引用该字符串也可以定义数组,示例如下:
    3
    使用复合赋值语句指定下标的定义索引数组的示例如下:
    4

    上例只给3个指定下标的元素赋值,所以数组长度为3。${name[*]}获取数组所有元素,${#name[*]}获取数组长度。

    2.定义关联数组

    关联数组使用任意字符串来访问元素。关联数组用下面的形式来创建:

    # 声明一个关联数组(必须先声明为关联数组)
    declare -A name
    # 可以使用单独给各个元素赋值的方式创建关联数组
    name[subscript]=value
    # 或者使用复合赋值语句创建数组并赋值
    # 对于关联数组,下标是必须的,使用键值对时,键不能缺失和为空,最后的缺失值被视为空字符串
    name=([subscript1]=value1 [subscript2]=value2 … )
    
    # 也可以在声明的同时给数组赋值
    declare -A name[subscript]=value
    declare -A name=([subscript1]=value1 [subscript2]=value2 … )
    

    使用单独给各个元素赋值的方式创建关联数组的示例如下:
    5
    使用复合赋值语句定义关联数组的示例如下:
    6
    在声明关联数组的同时给数组赋值的示例如下:
    7

    内部命令declarelocalreadonly都接受-a选项来指定索引数组,以及一个-A选项来指定关联数组。如果两个选项都有,则优先使用-A。内部命令read程序接受一个-a选项,将从标准输入中读取一组单词分配给数组,并且可以从标准输入读取值后赋给单个数组元素。内置命令setdeclare可以以允许将数组值作为输入重用的方式显示数组值。

    二、获取数组元素

    1.获取单个元素的值

    获取数组中单个元素的值的语法如下:

    # 获取名为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]}
    

    执行结果:
    8
    获取关联数组中单个元素的值的示例如下:

    #!/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"]}
    

    执行结果:
    9

    使用有效下标对变量的任何引用都是合法的,并且bash会在必要时创建一个数组。如果已为下标分配了值,则认为已设置数组变量。

    2.获取所有元素的值

    获取数组中所有元素的值的语法如下:

    # 都是获取名为name的数组中所有元素的值,如果数组中没有元素,则结果为空
    # 只有在被双引号包围时,*和@才有所不同
    # 被双引号包围时,${name[*]}扩展为一个单词,每个数组元素的值都由IFS的第一个字符分隔(一般是空格),而${name[@]}仍将数组中每个元素的值都扩展为独立的单词
    ${name[*]}
    ${name[@]}
    

    获取索引数组中所有元素的值的示例如下:

    #!/bin/bash
    
    array=("hello" "shell" 123 "java" "abc" 321)
    # 使用${name[*]}语法输出数组中所有元素的值
    echo ${array[*]}
    # 使用${name[@]}语法输出数组中所有元素的值
    echo ${array[@]}
    

    执行结果:
    10
    获取关联数组中所有元素的值的示例如下:

    #!/bin/bash
    
    declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
    # 使用${name[*]}语法输出数组中所有元素的值
    echo ${account[*]}
    # 使用${name[@]}语法输出数组中所有元素的值
    echo ${account[@]}
    

    执行结果:
    11
    以下示例可以看出${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
    

    执行结果:
    12

    3.获取所有元素的下标

    获取数组中所有元素的下标(索引)的语法如下:

    # 获取名为name的数组中所有元素的下标,双引号中的处理与特殊参数*和@类似
    # 所以${!name[*]}和${!name[@]}的区别与上面的${name[*]}和${name[@]}的区别类似
    ${!name[*]}
    ${!name[@]}
    

    获取索引数组中所有元素的下标的示例如下:

    #!/bin/bash
    
    array=("hello" "shell" 123 "java" "abc" 321)
    # 使用${!name[*]}语法输出数组中所有元素的下标
    echo ${!array[*]}
    # 使用${!name[@]}语法输出数组中所有元素的下标
    echo ${!array[@]}
    

    执行结果:
    13
    获取关联数组中所有元素的下标的示例如下:

    #!/bin/bash
    
    declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"]="qwer123" ["age"]=22 ["email"]="zhangsan01@xxx.com")
    # 使用${!name[*]}语法输出数组中所有元素的下标
    echo ${!account[*]}
    # 使用${!name[@]}语法输出数组中所有元素的下标
    echo ${!account[@]}
    

    执行结果:
    14

    三、获取数组及数组元素长度

    1.获取数组长度

    获取数组长度的语法如下:

    # 获取名为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[@]}
    

    执行结果:
    15

    2.获取指定数组元素的长度

    获取数组中指定元素的长度的语法如下:

    # ${#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]}
    

    执行结果:
    16
    获取关联数组中指定元素的长度的示例如下:

    #!/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"]}
    

    执行结果:
    17

    四、修改数组元素

    可以使用单独给元素赋值的方式来修改数组中指定元素的值:

    # 通过给单个元素赋值的方式来修改数组中指定元素的值
    # 指定的下标不存在会添加元素
    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[*]}
    

    执行结果:
    18
    修改关联引数组中指定元素的值的示例:

    #!/bin/bash
    
    declare -A account=(["uid"]="a123776" ["username"]="zhangsan01" ["password"
    
    下一篇:没有了