搜索
您的当前位置:首页正文

【Shell脚本】Shell编程之数组

来源:易榕旅网


一.数组

1.基本概念

  • 数组(Array)是有序的元素序列
  • 若将有限个类型相同的变量的集合命名,那么这个名称为数组名
  • 组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量
  • 用于区分数组的各个元素的数字编号称为下标
  • 数组是在编程中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式

2.定义数组的方法

2.1.方法一

数组名=(value0 value1 value2 ...)

2.2.方法二

数组名=([0]=value [1]=value [2]=value ...)

2.3.方法三

列表名="value0 value1 value2 ..."

数组名=($列表名)

2.4.方法四

数组名 [0]="value"
 
数组名 [1]="value"
 
数组名 [2]="value"

2.5.查看数组长度

echo ${#数组名[@]}

echo ${#数组名[*]}

2.6.查看数组元素下标

echo ${!数组名[@]}

echo ${!数组名[*]}

3.数组分片

echo ${数组名[@]:下标:长度}

echo ${数组名[*]:下标:长度}

4.数组字符替换

echo ${数组名[@]/旧字符/新字符}

数组名=(${数组名[*]/旧字符/新字符})        通过重新定义的方式实现永久替换

4.1.临时替换

4.2.永久替换

5.数组删除

unset 数组名[下标]                删除数组的某个下标

unset 数组名                     删除数组

5.1.删除某个下标

5.2.删除整组

6.数组遍历和重新定义

arr=(1 2 3 4 5)
n=0
for i in ${arr[@]}
do
    arr[$n]=$[i*2]
    let n++
done

7.数组追加元素

7.1.方法一

数组名[新下标]=新元素

7.2.方法二

数组名[数组长度]=新元素                        仅适用于完整的数组

7.3.方法三

数组名+=(新元素1 新元素2 ....)

7.4.方法四

数组名=("${数组名[@]}" 新元素1 新元素2 ....)

8.用函数判断数组是否完整

#!/bin/bash
#判断一个数组是否完整
array1=(10 20 30 40 50 60)
array3=([0]="a" [1]="b" [2]="c" [3]="d" [5]="f")

#获取数组长度
length1=${#array1[@]}
length3=${#array3[@]}

#获取长度n - 1 的下标
last1=$[length1 - 1]
last3=$[length3 - 1]

#获取数组最后一个元素下标
last1_num=$(echo ${!array1[@]} | awk '{print $NF}')
last3_num=$(echo ${!array3[@]} | awk '{print $NF}')

#判断长度n - 1 的下标 是否与 数组最后一个元素下标 相同
if [ $last1 -eq $last1_num ];then
     echo "array1 数组完整"
else
     echo "array1 数组不完整"
fi

if [ $last3 -eq $last3_num ];then
     echo "array3 数组完整"
else
     echo "array3 数组不完整"
fi

9.向函数传数组参数

函数名() {
     数组2=($@)         #在函数体内将传入的列表重新组成数组
     ....
}

函数名 ${数组1[@]}      #在函数体外将数组分解成列表传入

10.从函数返回数组

函数名(){
    ....
    echo ${数组2[@]}     #在函数体内以列表形式返回值
}

数组1=(函数名 参数)      #在函数体外将函数执行的结果重新组合成数组

10.1.实操

#!/bin/bash
test1() {
      #在函数里将传入的元素列表重新组成数组
      arr2=($@)
      #遍历数组方法一
      for ((i=0; i<${#arr2[@]}; i++))
      do
           arr2[$i]=$[${arr2[$i]} *2]
      done

      #从函数返回数组
      echo ${arr2[@]}
      #遍历数组方法二
      #n=0
      #for i in ${arr2[@]}
      #     arr2[$n]=$[$i * 2]
      #     let n++
      # done
}

arr1=(50 40 30 20 10)
#        向函数传入数组
result=$(test1 ${arr1[@]})

#在函数体外将函数返回的值列表重新组成数组
arr1=($result)

echo "arr double以后的值为 ${arr1[@]}"

二.数组排序算法(拓展)

1.冒泡排序

1.1.概述

类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断的向前移动

1.2.基本思想

冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到

数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡

一样从底部上升到顶部

1.3.算法思路

冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因

为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用

于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少

1.4.实操

[root@localhost day14]# vim demo4.sh
[root@localhost day14]# bash demo4.sh
原始数组的顺序为 63 4 24 1 3 15
排序后数组顺序为 63 24 15 4 3 1

#!/bin/bash
#冒号排序算法

arr=(63 4 24 1 3 15)
echo "原始数组的顺序为 ${arr[@]}"

#获取数组长度
length=${#arr[@]}

#外循环确定比较轮数,比较论述为数组长度 - 1
for ((a=1; a<length; a++))
do
    #内循环来比较相邻两个元素,从小到大排序;较大的往后放,每轮的比较次数随着轮数增加而减少
    for ((b=0; b<length-a; b++))
    do
         #获取左边比较元素的值
         left=${arr[$b]}
         #获取右边比较元素的值
         c=$[b + 1]
         right=${arr[$c]}
         #比较相邻两个元素,如果左边的元素值大于右边的,则元素互换
         if [ $left -lt $right ];then
               tmp=$left
               #将原来右边元素的值定义到左边元素
               arr[$b]=$right
               #将原来左边元素的值定义到右边元素
               arr[$c]=$tmp
         fi
    done
done

    echo "排序后数组顺序为 ${arr[@]}

2.直接选择排序

2.1.概述

与冒泡排序相比,直接选择排序的交换次数更少,所以速度会快些

2.2.基本思想

将指定排序位置与其它数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,

不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始序),

这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式

2.3.相关实操

[root@localhost day14]# vim demo5.sh
[root@localhost day14]# bash demo5.sh
原始数组的顺序为 63 4 24 1 3 15
排序后的数组顺序为 1 3 4 15 24 63

#!/bin/bash
#直接选择排序

arr=(63 4 24 1 3 15)
echo "原始数组的顺序为 ${arr[@]}"

length=${#arr[@]}
#外循环 确定排序轮数,轮数为数组长度 - 1
for ((a=1; a<length; a++))
do
    #定义初始最大元素的下标为0
    max=0
    #内循环 确定当前比较轮数最大的元素下标
    for ((b=1; b<length-a; b++))  #设置作为与初始最大元素比较的元素下标范>围
    do
         if [ ${arr[$b]} -gt ${arr[$max]} ];then
             max=$b
         fi
    done
    #用当前轮数最大的元素与当前轮数最后一个元素交换位:
    last=$[length - a]
    tmp=${arr[$last]}
    arr[$last]=${arr[$max]}
    arr[$max]=$tmp
done
    echo "排序后的数组顺序为 ${arr[@]}"

3.反转排序

3.1.概述

以相反的顺序把原有数组的内容重新排序

3.2.基本思想

把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所

有数组元素反转替换

3.3.实操

[root@localhost day14]# vim demo6.sh
[root@localhost day14]# bash demo6.sh
输入一个数组的列表: 50 42 32 11 5
原始数组的顺序为 50 42 32 11 5

#!/bin/bash
#反转排序
filp() {
array=($@)
length=${#array[@]}

for ((a=0; a<length/2; a++))
do
    tmp=${array[$a]}
    last=$[length-1-a]
    array[$a]=${array[$last]}
    array[$last]=$tmp
done

echo "反转排序后的数组顺序为 ${array[@]}"
}
read -p "输入一个数组的列表: " num
arr=($num)
echo "原始数组的顺序为 ${arr[@]}"

filp ${arr[@]}

因篇幅问题不能全部显示,请点此查看更多更全内容

Top