自动化运维必须要学的Shell脚本之——数组(冒泡排序和反转排序等)
Posted 码海小虾米_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自动化运维必须要学的Shell脚本之——数组(冒泡排序和反转排序等)相关的知识,希望对你有一定的参考价值。
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.1 将数组传入函数返回新的数组
1.如果将数组作为函数的参数,函数只会取数组变量的第一个值,如下:
2.解决上述的问题:需要将数组变量的值分解成单个的值,然后将这些值作为函数参数使用,在函数内部,再将所有的参数重新组合成一个新的数组变量。
2.2 将数组传入函数进行计算返回结果
结果:
二、数组的排序(冒泡/直接选择/反向)
2.1 冒泡排序
1.概述:类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断向前移动。
2.基本思想:冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一 样从底部上升到顶部。
3.算法思路:冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减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[*]}"
结果:
2.1 直接选择排序
1.概述:与冒泡排序相比,直接选择排序的交换次数更少,所以速度会快些。
2.基本思想:将指定排序位置与其它数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一 个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。
6 # 定义数组,无顺序即可
7 array=(44 22 55 91 4 6 42 100 333 12)
8 echo "没排序的数组为: ${array[*]}"
9 # 将数组的长度赋予变量lg
10 lg=${#array[*]}
11 # 确定循环比较的次数
12 for ((i=1;i<$lg;i++)){
13 # 定义变量index为0,作为数组的下标
14 index=0
15 # 使用循环进行比较,每轮比较的次数为lg-i
16 for ((j=0;j<$lg-i;j++)){
17 #对比获取最大值元素的索引位置,如果当前数比index0大
18 if [ ${array[$j]} -gt ${array[$index]} ];then
19 # 就把该元素对应的下标索引给index
20 index=$j
21 fi
22 }
23 # 定义最后每轮最后元素的下标为last
24 last=$[$lg-$i]
25 # 定义临时变量用来接受最后的元素的值
26 temp=${array[$last]}
27 # 将下标索引为index的数给当前数组的最后一个元素
28 array[$last]=${array[$index]}
29 # 将之前临时变量temp的值给下标为index的元素,实现对换
30 array[$index]=$temp
31 }
32 echo "排序后的数组为: ${array[*]}"
结果:
2.1 反转排序
1.概述:以相反的顺序把原有数组的内容重新排序。
2.基本思想:把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换。
6 # 定义数组随便,我这里按顺序方便对比
7 array=(a b c d e f g)
8 echo "反转之前的数组为: " ${array[*]}
9
10 # 取出数组的长度
11 lg=${#array[*]}
12 # 使用循环,次数为长度的一般即可,因为反转是相互的
13 for ((i=0;i<lg/2;i++)){
14 # 每次反转的时候定义一个临时变量用来接受此次反转的第一个变量
15 temp=${array[$i]}
16 # 将此次反转操作时的最后一个变量赋予给此次反转的第一个
17 array[$i]=${array[$lg-$i-1]}
18 # 然后将临时变量接收的值赋予给此次反转的最后一个
19 array[$lg-$i-1]=$temp
20 }
21 echo "反转之后的数组为: " ${array[*]}
结果:
以上是关于自动化运维必须要学的Shell脚本之——数组(冒泡排序和反转排序等)的主要内容,如果未能解决你的问题,请参考以下文章
自动化运维必须要学的Shell脚本之——编程规范和变量详细解读