• 【shell】shell 数组处理


    目录

    极简

    简述

    遍历数组

    空数组

    数组做参数 

    数组添加元素

    数组去重复

    Shell数组拼接

    判断数组是否包含某个元素

    Shell删除数组元素

    关联数组

    awk数据列存入数组


    极简

    array_name=(value1 value2 ... valuen)

    array_name[0]=value0

    数组元素值:${array_name[index]}

    所有数组的元素: ${my_array[*]}"

    数组元单元个数: ${#my_array[*]}"

    key-value

    declare -A  array_name

    array_name["google"]="www.google.com"

    array_name["index"]

    获取数组的所有键:echo "键为: ${!site[*]}"

    简述

    Bash Shell 只支持一维数组(不支持多维数组)

    Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
    array_name=(value1 value2 ... valuen)

    也可以使用数字下标来定义数组:
    array_name[0]=value0
    array_name[1]=value1
    array_name[2]=value2

    读取数组元素值的一般格式是:
    ${array_name[index]}

    关联数组

    declare -A array_name
    -A 选项就是用于声明一个关联数组。

    关联数组的键是唯一的。

    以下实例我们创建一个关联数组 site,并创建不同的键值:

    实例
    declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
    我们也可以先声明一个关联数组,然后再设置键和值:

    实例
    declare -A site
    site["google"]="www.google.com"
    site["runoob"]="www.runoob.com"
    site["taobao"]="www.taobao.com"

    访问关联数组元素可以使用指定的键,格式如下:

    array_name["index"]

    获取数组中的所有元素
    使用 @ 或 * 可以获取数组中的所有元素
    echo "数组的元素为: ${my_array[*]}"
    echo "数组的元素为: ${my_array[@]}"

    获取数组长度的方法与获取字符串长度的方法相同
    echo "数组的元素个数为: ${#my_array[*]}"
    echo "数组的元素个数为: ${#my_array[@]}"

    获取数组的所有键
    echo "数组的键为: ${!site[*]}"
    echo "数组的键为: ${!site[@]}"

    遍历数组

    shell 数组遍历的3种方法

    • 标准的for循环

    • for … in循环方法

    • While循环法


       array=( A B C D 1 2 3 4)
        for(( i=0;i<${#array[@]};i++)) #${#array[@]}数组长度

        do
        echo ${array[i]};
        done;
     

        for element in ${array[@]}     #也可以写成for element in ${array[*]}
        do
        echo $element
        done
     
        echo "2.2 遍历(带数组下标)"
        for i in "${!array[@]}";   
        do 
        printf "%s\t%s\n" "$i" "${array[$i]}"  
        done
       
       echo "3.While循环法"
       i=0  
       while [ $i -lt ${#array[@]} ]  
       #当变量(下标)小于数组长度时进入循环体
       do  
        echo ${array[$i]}  
        #按下标打印数组元素
        let i++  
       done

    遍历
    cnt=${#my_array[@]}
    for ((i=0;i < ${cnt};i++))
    do
    echo ${array_name[i]}
    done
     

    空数组

    vim ./test.sh 

    #!/bin/bash
    #
    arry2=(That sa non empty array)
    array3=()
    array4=('')
    #
    ARRAY()
    {
    echo "Element of arry2 is:${array2[@]}."
    echo "Element of array3 is:${array3[@]}."
    echo "Element of array4 is:${array4[@]}."
    }

    ARRAY

    array3[0]="my"
    array3[2]="u"

    ARRAY

    array4[5]=9
    echo "len of array3 is:${#array3[@]}."
    echo "Element of array4 is:${array4[@]}."
    echo "len of array4 is:${#array4[@]}."

    [root@localhost vmshare]# ./test.sh 


    Element of arry2 is:.
    Element of array3 is:.
    Element of array4 is:.
    Element of arry2 is:.
    Element of array3 is:my u.
    Element of array4 is:.
    len of array3 is:2.
    Element of array4 is: 9.
    len of array4 is:2.
     

    数组做参数 

    #!/bin/bash
     
    function showArr()

    {
        arr=($1)
        for i in ${arr[*]};

        do
            echo $i
        done
    }
     
    regions=("GZ" "SH" "BJ")
    showArr  "${regions[*]}"

    数组添加元素

    (摘自:Shell数组添加元素及注意事项_lhttps://www.jb51.net/article/201792.htm)

    方法1:

    array_name+=(value1 ... valueN)

    特点:不需要元素下标连续,可以添加多个元素,添加后元素下标不会重置,不存在元素覆盖的风险。

    注意:唯一要注意的就是“+=”前后不能有空格

    方法2:

    array_name[index]=value

    注意:如果 array_name[index]原本有值,会被覆盖

    方法3:

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

    #或array_name[${#array_name[*]}]=value

    注意:此方法有一个前提,就是数组中的元素下标必须是连续的,否则会存在替换已有元素的风险。例如:

    arr=([1]="a" [2]="b")
    echo ${arr[@]}
    arr[${#arr[@]}]="c"
    echo ${arr[@]}

    实际上并有添加元素,而是将下标为2的元素值“b”替换为了“c”。

    方法4:

    array_name=("${array_name[@]}" value1 ... valueN)

     这种方式不需要下标连续,可同时添加多个元素。

    注意:

    1、数组中原有元素的下标会重置,会从0开始变成连续的,如果不希望改变下标则不能使用这种方式。 

    2、双引号不能省略,否则,当数组array_name中存在包含空格的元素时会按空格将元素拆分成多个。

    3、不能将“@”替换为“*”,虽然在输出数组元素时可以相互替换,如果替换为“*”,不加双引号时与“@”的表现一致,加双引号时,会将数组array_name中的所有元素作为一个元素添加到数组中。类似于特殊变量$@和$*的区别。

    数组去重

    #!/bin/bash
    #定义数组
    arr=()
    #用+ 的方式给数组添加
    arr+=(3 5 8)
    arr+=(4 5 3)
    echo "去重前:"${arr[@]}
    # 去重
    arr=($(awk -v RS=' ' '!a[$1]++' <<< ${arr[@]}))
    echo "去重后:"${arr[@]}

    shell 数组去重,去掉重复_https://blog.csdn.net/weixin_35795555/article/details/111312547

    Shell数组拼接

    array_new=(${array1[@]} ${array2[@]})

    array_new=(${array1[*]} ${array2[*]})

    https://haicoder.net/shell/shell-array-contact.html

    判断数组是否包含某个元素

    array=( element1 element2 element3 )

    var="element1"

    echo "${array[@]}" | grep -wq "$var" && echo "Yes" || echo "No"

    推荐使用最原始的 安全可靠:

    for i in ${array[@]} ;do  [ "$i" == "$var" ] && echo "yes" ;done

    判断某个元素是否在数组内https://www.cnblogs.com/thatsit/p/bash-shu-zupan-duan-mou-ge-yuan-su-shi-fou-zai-shu.html

    1. 网上其他方案的缺陷:
    2. 1)
    3. [[ ${array[@]/${var}/} != ${array[@]} ]] && echo "Yes" || echo "No"   
    4. 该方案遇到:
    5. ARCHS=("aarch64" "x86_64" "auto")
    6. [[ ${ARCHS[@]/${arch_specify}/} == ${ARCHS[@]} ]] && echo "Input arch error!should be one of:${ARCHS[@]}"
    7. 一旦入参是:aarch
    8. aarch64/aarch=64
    9. 就变成:
    10. + [[ 64 x86_64 auto == aarch64 x86_64 auto ]]

    Shell删除数组元素

    unset 关键字来删除数组元素

    unset array_name[index]  #删除第index个

    unset array_name            #删除整个数组

    根据元素删除

    # 删除'b'

    array=(a b c d a b c d)

    array=( ${array[*]/b} )        #将*换成 @, 结果一致

    从一个数组中排除另一个数组中的所有内容

    # 需要从拟卸载的列表里排除的包,一般为BROS项目组发布其它的组件包
    readonly EXCLUDELIST=(a b)
    # 需要卸载的包的列表,此数组是为了卸载早期bros版本命名不规范可能留下的安装包
    NEED2REMOVE=(a b c d a b c d)
    # 从卸载列表中排除组件
    function func_exclude_components(){
        for((i=0; i<${#EXCLUDELIST[@]}; i++)); do
            NEED2REMOVE=(${NEED2REMOVE[@]/${EXCLUDELIST[i]}})
        done
    }
    func_exclude_components
    echo ${NEED2REMOVE[@]}
    #-------------------------
    c d c d

    摘自:shell 从数组中删除元素_https://blog.csdn.net/qq_29935433/article/details/122688370

    关联数组

    (摘自:shell脚本中实现数组变量-阿里云开发者社区 (aliyun.com)

    关联数组与普通数组不同之处在于,关联数组的索引不再是默认的整数,而是由管理员自己定义

    格式:数组名=([][][索引1]=元数值 [索引2]=元数值)

    像存在的数组中增加索引:数组名+=([索引3]=元数值)

    例如:userinfo=([user]=jiangxiaolong [age]=20 [sex]=boy)

    userinfo+=([sy]=yunwei)

    shuzu2=’([0]=“zero” [1]=“one” [2]=“two” [3]=“three” [4]=“four” [5]=“five” [6]=“six”)’

    declare -a shuzu3=’([0]=“1” [1]=“2” [2]=“3” [3]=“4” [4]=“5” [5]=“6” [6]=“7” [7]=“linux shell” [20]=“tomcat”)

    查看:

    [root@localhost ~]# declare -a
      declare -a shuzu2='([0]="zero" [1]="one" [2]="two" [3]="three" [4]="four" [5]="five" [6]="six")'
      declare -a shuzu3='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="linux shell" [20]="tomcat")'

    访问数组元素:

    [root@localhost ~]# echo ${array1[0]} 访问数组中的第一个元数
    [root@localhost ~]# echo ${array1[@]}   访问数组中的所有元数,等同于echo ${array1[*]}
    [root@localhost ~]# echo ${#array1[@]}  统计数组中元素的个数
    [root@localhost ~]# echo ${!arrar2[@]}  获取数组元数的索引
    [root@localhost ~]# echo ${array1[@]:1} 从数组下标1开始,也就是除了索引位0,其余都会显示
    [root@localhost ~]# echo ${array1[@]:1:2} 从数组下标1开始,访问两个元素,也就是从索引1开始往后显示2个

    awk数据列存入数组

    user_list=($(ps -ef|grep ora_pmon|grep -v grep| awk '{print $1}'))

    1. cat > test.sh << 'EOF'
    2. index_dir_map=()
    3. index_kernels_map=()
    4. orign=${IFS}
    5. IFS=$'\n'
    6. for line in $(tr -cd "[:print:]\n" < share_map.txt|grep -vE "^#|^$")
    7. do
    8. index=$(echo "$line"|awk '{print $1}')
    9. dir=$(echo "$line"|awk '{print $2}')
    10. kernels=$(echo "$line"|awk '{print $3}')
    11. index_dir_map+=(["${index}"]="${dir}")
    12. index_kernels_map+=(["${index}"]="${kernels}" )
    13. echo "index_dir_map:len=${#index_dir_map[*]}****${!index_dir_map[*]}****${index_dir_map[*]}"
    14. echo "index_kernels_map:len=${#index_kernels_map[*]}****${!index_kernels_map[*]}****${index_kernels_map[*]}"
    15. done
    16. IFS=${orign}
    17. #列出所有键值对
    18. for key in ${!index_dir_map[@]}
    19. do
    20. echo "${key} -> ${index_dir_map[$key]}"
    21. done
    22. #列出所有键值对
    23. echo "index----->kernels"
    24. for key in ${!index_kernels_map[@]}
    25. do
    26. echo "${key} -> ${index_kernels_map[$key]}"
    27. done
    28. EOF
    29. chmod +x test.sh
    30. ./test.sh

  • 相关阅读:
    图片批量压缩工具哪个好用?这3个工具可以解决你的压缩烦恼
    我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:JVM的整体结构
    vb.net的日期工具类
    自学java怎么入门?
    智能座舱行为识别数据解决方案,助力打造第三空间新体验
    公众号如何让更多人看到?这三种方法超有效!
    数据库——数据库备份与恢复
    鸿蒙应用ArkTS开发- 选择图片、文件和拍照功能实现
    Java版人脸跟踪三部曲之一:极速体验
    第七十天 c++perimer70~115string类型总结
  • 原文地址:https://blog.csdn.net/bandaoyu/article/details/126940631