自动化运维必备之Shell数组,超详细解释!

Shell脚本之数组



前言


1. shell数组

1.1 什么是数组

  • 数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。

  • 与大部分编程语言类似,数组元素的下标由 0 开始。

  • Shell 数组用括号来表示,元素用"空格"符号分割开

1.2 数组的语法格式

  • 格式一:
数组名=(value1 value2 ... valuen)
arr_number=(1 2 3 4 5 6 7 8 9)
  • 格式二:
数组名=([0]=value0 [1]=value0 [2]=value0 ...)
arr_number=([0]=1 [1]=2 [2]=3 [3]=4)
  • 格式三:
列表名:“value1 value2 valueN ..."
数组名=($列表名)
list_number="1 2 3 4 5 6"
arr_number=($list_number)
  • 格式四:
数组名[0]="value"
数组名[1]="value"
数组名[2]="value"
arr_number[0]=1
arr_number[1]=2
arr_number[2]=3

1.3 数组的数据类型

  • 数值类型
  • 字符类型
  • 使用 “ ”(双引号) 或者 ‘ ’ (单引号)定义

1.4 获取数组的长度

在这里插入图片描述

arr_length=${
    
    #arr_number[@]}
		   ${
    
    #arr_number[*]}
echo $arr_length 

1.5 获取数组的列表

echo ${arr_number[*]}
echo ${arr_number[@]}

1.6 获取数组下标对应的值

arr_number=(1 2 3 4 5 6 7 8 9 0)
arrindex3=${arr_number[3]}
echo $arrindex3 

1.7 遍历数组

arr_number=(0 1 2 3 4 5 6 7 8 9)

for i in ${arr_number[@]}
do
    echo $i
done

1.8 数组切片

arr_number=(0 1 2 3 4 5 6 7 8 9)

echo "输出整个数组: " ${arr_number[@]}
echo "取出数组1到3: " ${arr_number[@]:1:3}
echo "取出数组5到9: " ${arr_number[@]:5:5}
echo "取出数组0后面所有: " ${arr_number[@]:0}

1.9 数组替换

echo " ${arr[@]/4/666}:这种写法会输出替换后的数组,但是是临时的,并未改变原数组
arr=(${arr[@]/4/666}):使用重新赋值,可以修改原数组

arr=(0 1 2 3 4 5 6 7 8)
echo "初始的数组为: " ${arr[@]}
echo "输出替换的数组:" ${arr[@]/4/666}		
echo "替换后查看原数组为: " ${arr[@]}

arr=(${arr[@]/4/666})
echo "替换后的数组为: " ${arr[@]}

1.10 数组删除和指定下标的值删除

1.11 数组追加元素

  • 方法一 :直接使用下标进行元素的追加
array_name[index]=value
  • 方法二:将数组的长度作为下标进行追加元素(比如下面例子,原数组的长度为5,数组内最后一个元素的下标为4,所以使用5意思也是追加,跟方法一道理一样)
array_name[${array_name[@]}]=value
  • 方法三:

双引号不能省略,否则,当数组array name中存在包含空格的元素时会按空格将元素拆分成多个
不能将“@”替换为 “ * ”,如果替换为“ * ”,不加双引号时与"@"的表现一致,加双引号时,会将数组array name中的所有元素作为一个元素添加到数组中。

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

使用循环测试 加不加双引号的情况下,使用@和 * 的区别

  • 方法四:使用+=进行追加

待添加元素必须用“()”包围起来,并且多个元素用空格隔开

array_name+=(value1...valueN)

2. 将数组作为函数的参数

2.1 将数组传入函数返回新的数组

1.如果将数组作为函数的参数,函数只会取数组变量的第一个值

2.解决上述的问题:需要将数组变量的值分解成单个的值,然后将这些值作为函数参数使用,在函数内部,再将所有的参数重新组合成一个新的数组变量。

2.2 将数组传入函数进行计算返回结果

3. 数组的排序(冒泡/直接选择/反向)

3.1 冒泡排序

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

基本思想:冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一 样从底部上升到顶部。

算法思路:冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。

# 定义一个数组,内容无序
array_num=(77 20 67 4 35 88 55)
# 输出未排序之前的数组,方便和后面做对比
echo "没有进行排序之前的数组: " ${array_num[*]} 
# 定义一个变量,代表数组的长度
arr_length=${
    
    #array_num[*]}
# 外循环作用将数组进行循环,次数为数组的长度-1
for ((i=1;i<$arr_length;i++)){
    
    
    # 内循环为数组内相邻两个元素的对比
    for ((j=0;j<$arr_length-i;j++)){
    
    
    # 将数组的第一个元素赋予给变量first
    first=${array_num[$j]}
    # 将数组的第二个元素赋予给变量second
    second=${array_num[$[$j+1]]}
        # 进行判断,如果第一个数大于第二个数
        if [ $first -gt $second ]
        then
            # 使用临时变量接收第一个数
            temp=$first
            # 然后将第二个数给第一个数,因为第一个数大,需要换位
            array_num[$j]=$second
            # 最后再将临时变量的值赋给第一个数
            array_num[$[$j]+1]=$temp
        fi
    }
}
echo "从小到大排序后的数组为:  ${array_num[*]}"

3.2 直接选择排序

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

基本思想:将指定排序位置与其它数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一 个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。

#定义数组,无顺序即可
array=(44 22 55 91 4 6 42 100 333 12)
echo "没排序的数组为: ${array[*]}" 
#将数组的长度赋予变量lg
lg=${
    
    #array[*]}
#确定循环比较的次数
for ((i=1;i<$lg;i++)){
    
    
    #定义变量index为0,作为数组的下标
    index=0
    #使用循环进行比较,每轮比较的次数为lg-i
    for ((j=0;j<$lg-i;j++)){
    
    
    #对比获取最大值元素的索引位置,如果当前数比index0大
         if [ ${array[$j]} -gt ${array[$index]} ];then
              #就把该元素对应的下标索引给index
              index=$j
         fi
     }
     #定义最后每轮最后元素的下标为last
     last=$[$lg-$i]
      #定义临时变量用来接受最后的元素的值
      temp=${array[$last]}
       #将下标索引为index的数给当前数组的最后一个元素
      array[$last]=${array[$index]}
      #将之前临时变量temp的值给下标为index的元素,实现对换
      array[$index]=$temp
 }
echo "排序后的数组为: ${array[*]}"

3.3 反转排序

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

基本思想:把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换。

# 定义数组随便,我这里按顺序方便对比
array=(a b c d e f g)
echo "反转之前的数组为: " ${array[*]}

# 取出数组的长度
lg=${
    
    #array[*]}
# 使用循环,次数为长度的一般即可,因为反转是相互的
for ((i=0;i<lg/2;i++)){
    
    
     # 每次反转的时候定义一个临时变量用来接受此次反转的第一个变量
     temp=${array[$i]}
     # 将此次反转操作时的最后一个变量赋予给此次反转的第一个
     array[$i]=${array[$lg-$i-1]}
     # 然后将临时变量接收的值赋予给此次反转的最后一个
     array[$lg-$i-1]=$temp
}
echo "反转之后的数组为: " ${array[*]}

总结

猜你喜欢

转载自blog.csdn.net/weixin_55609819/article/details/120293488