shell之数组、向函数传数组参数、从函数返回数组、冒泡排序直接选择排序、反转排序
一、数组
1.1、数组定义的方法
方法一:
数组名=(value0 valuel value2 ...)
方法二:
数组名=([0]=value [1]=value [2]=value ...)
方法三:
列表名="value0 valuel value2 ..."
数组名=($列表名)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201223164531499.png)
方法四:
数组名[0]="value"
数组名[1]="value"
数组名[2]="value"
1.2、数组数据类型
(1)、数值类型
(2)、字符类型
使用 ” “ 或 ’ ‘定义
1.3、获取数组长度
arr number=(1 2 3 45)
arr _length=${#arr_number[*]}
${#arr_number[@] }
echo $arr_length
1.4、读取某下标赋值
arr _index2=${arr_number[2]}
echo $arr_index2
1.5、数组遍历
#! /bin/bash
arr number=(1 2 3 4 5)
for V in ${arr_ number[@] }
do
echo $v
done
1.6、数组切片
arr=(12345)
echo ${arr[@] } #输出整个数组
echo $arr[@] :0:2} #获取 $ {数组名[@或*] :起始位置:长度}的值
echo ${arr[@] :2:3}
1.7、数组替换
arr=(123 4 5)
echo ${arr[@]/4/66} #${数组名[@或*]/查找字符/替换字符}
echo ${arr[@] } #并不会替换数组原有内容
arr= (${arr[@]/4/66}) #要实现改变原有数组,可通过重新赋值实现
echo ${arr[@]}
1.8、数组删除
arr=(12345)
unset arr #删除数组
echo ${arr[*] }
arr=(12345)
unset arr [2] #删除第三个元素
echo ${arr[*] }
1.9、数组追加元素
方法一:
array_ name [index] =value
方法二:
array_ name [${#array_ name[@]}]=value
方法三:
array name=("$ {array name[@] } " value1 . ..valueN)
双引号不能省略,否则,当数组array_ name中存在包含空格的元素时会按空格将元素拆分成多个
不能将“@”替换为“”,如果替换为“”,不加双引号时与“@”的表现一 致,加双引号时,会将数组array_name中的所有元素作为一 个元素添加到数组中
方法四:
array_ name+= (value1 ... valueN)
待添加元素必须用“()"包围起来,并且多个元素用空格分隔
二、向函数传数组参数
如果将数组变量作为函数参数,函数只会取数组变量的第一个值。
错误示范:
[root@localhost ~]# vim test1.sh
[root@localhost ~]# . test1.sh
test1 ()
echo "接收到的参数列表: $@"
newarrary=$1
echo "新数组的值为: $ {newarrary[*]}"
}
array=(3 2 1 4 5)
echo "原始数组的值为: ${array[*]}"
test1 $array #此处输出的数组方式有错,导致获取不到完整的数组值
解决这个问题则需要将数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,再将所有的参数重新组合成一个新的数组变量。
test2 () {
newarrary= ($ (echo $@))
echo "新数组的值为: ${newarrary[*]}"
}
array=(321 4 5)
echo "原始数组的值为: ${array[*]}"
test2 ${array[*]}
三、从函数返回数组
举例1:(加法传参运算)
[root@xwj shuzu1]#vim c.sh
#!/bin/bash
test2 () {
abc1=(`echo $@`)
sum=0
for i in ${abc1[*]}
do
sum=$[$sum + $i]
done
echo "$sum"
}
abc=(3 2 1 4 5)
test2 ${abc[*]}
[root@xwj shuzu1]#chmod +x c.sh
[root@xwj shuzu1]#./c.sh
15
举例2:(乘法传参运算)
[root@xwj shuzu1]#vim c.sh
#!/bin/bash
test3 () {
abc1=(`echo $@`)
for ((i=0;i<=$[$# - 1];i++)) #$#是原始数组的元素个数,这里是取出新数组的索引值是从0-4
do
abc1[$i]=$[${abc1[$i]} * 2] #这里是将每个原始索引对应的元素值乘以2传到新的数组中对应的索引的元素中去
done
echo "${abc1[*]}" #输出新的数组
}
abc=(1 2 3)
test3 ${abc[*]}
[root@xwj shuzu1]#./c.sh
2 4 6
四、数组排序算法
4.1、冒泡排序
类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断的向前移动。
基本思想:
冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置) ,这样较小的元素就像气泡一样从底部上升到顶部
算法思路:
冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。
#!/bin/bash
abc=(20 10 60 40 50 30) #定义一个数组
echo "原数组的排列顺序为:${abc[*]}"
length=${#abc[*]} #定义原数组的长度为length变量
for ((i=1;i<$length;i++)) #定义排序轮次
do
for ((k=0;k<$length-i;k++)) #确定第一个元素的索引位置
do
first=${abc[$k]} #定义第一个元素的值
j=$[$k+1] #定义第二个元素的索引号
second=${abc[$j]} #定义第二个元素的值
if [ $first -gt $second ] #第一个元素和第二个元素比较,如果第一个元素比第二个元素大则互换
then
temp=$first #把第一个元素的值保存在临时变量temp中
abc[$k]=$second #把第二个元素的值赋给第一个元素
abc[$j]=$temp #把原第一个元素的值,赋给第二个元素
fi
done
done
echo "排序后数组的排列顺序为${abc[*]}" #输出排序后的数组
[root@xwj shuzu1]#./g.sh
原数组的排列顺序为:20 10 60 40 50 30
排序后数组的排列顺序为10 20 30 40 50 60
4.2、直接选择排序
与冒泡排序相比,直接选择排序的交换次数更少,所以速度会快些。
基本思想:
将指定排序位置与其它数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始排序) ,这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。
[root@xwj shuzu1]#vim d.sh
#!/bin/bash
abc=(63 4 24 1 3 15) #定义一个数组
echo "原数组的排列顺序为${abc[*]}"
length=${#abc[*]} #定义原数组的长度,这里原数组的长度为6
for ((i=1;i<$length;i++)) #这里是定义比较的轮数,比较5次
do
index=0 #表示从索引0开始比较
for ((k=1;k<=$length-i;k++)) #这里是确定用于比较的第一个元素的索引范围,比如已经定义了从索引0开始了,所以和0进行比较的范
围就是从索引1-5了
do
first=${abc[$k]} #定义与index相比较的索引的取值为first
if [ $first -gt ${abc[$index]} ] #通过将index所在的索引的值与k所在的索引的值进行比较,获取最大元素的索引位置
then
index=$k #通过比较将较大的数定义到index中,进行下一轮的比较
fi
last=$[$length-$i] #获取在比较的范围中的最后一个元素的索引
temp=${abc[$last]} #将上一步获取到的最后一个元素的索引的值保存到临时变量temp中
abc[$last]=${abc[$index]} #把最大上面for循环比较出来的最大元素的值赋值给最后一个元素
abc[$index]=$temp #把原来最后一个元素的值赋给原来最大值的位置的元素
done
done
echo "排序后数组的排列顺序为${abc[*]}" #输出排序后的数组
[root@xwjj shuzu1]#chmod +x e.sh
[root@xwj shuzu1]#./e.sh
原数组的排列顺序为63 4 24 1 3 15
排序后数组的排列顺序为1 3 4 15 24 63
4.3、反转排序
以相反的顺序把原有数组的内容重新排序。
基本思想:
把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,1以此类推,直到把所有数组元素反转替换。
[root@xwj shuzu1]#vim f.sh
#!/bin/bash
abc=(10 20 30 40 50 60) #定义一个数组
echo "反转前顺序:${abc[*]}"
length=${#abc[*]} #定义数组的长度为length
for ((i=0;i<$length/2;i++)) #定义数组的比较的范围,因为是两两进行比较,所以只需要比较length/2组就行
do
temp=${abc[$i]} #定义第一个元素为临时变量temp
abc[$i]=${abc[$length-1-$i]} #将同组的最后一个元素的值赋值给第一个元素,注意因为我们i是从0开始的,所以最后一个
元素的索引号是长度减去1之后再减去变量i的值才是最后一个索引的值
abc[$length-1-$i]=$temp #将同组的第一个元素的值赋值给最后一个元素
done
echo "反转排序后:${abc[*]}"
[root@xwj shuzu1]#chmod +x f.sh
[root@xwj shuzu1]#./f.sh
反转前顺序:10 20 30 40 50 60
反转排序后:60 50 40 30 20 10