Shell数组
一、数组定义
数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便,把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。
数组是用于储存多个相同类型数据的集合。
定义方法
(10 20 30 40 50 60) 0 1 2 3 4 5 #从0开始
方法一
数组名=(value0 value1 value2 ...)
例:
方法二
数组名=([0]=value [1]=value [2]=value ...)
例:
方法三
列表名='value0 value1 value2 ...' 数组名=($列表名)
例:
方法四
数组名[0]="value" 数组名[1]="value" 数组名[2]="value"
例:
二、获取数组长度
a=(1 2 3 4 5) echo ${#a[@]}
例:
三、获取数据列表
echo ${num[*]} echo ${num[@]}
例:
四、读取某下标赋值
num=([0]=10 [1]=20 [2]=30 [3]=40 [4]=50) echo ${num[3]}
echo ${num[2]}
例:
五、数组遍历
#!/bin/bash num=(10 20 30 40 50) for i in ${num[@]} >do >echo $i >done
例:
六、数组切片
num=(10 20 30 40 50) echo ${num[@]:2:1} echo ${num[@]:3:1}
例:
七、数组替换
num=(10 20 30 40 50) echo ${num[@]/50/80} num=(${num[@]/40/70}) echo ${num[@]}
例:
八、数组删除
num=(10 20 30 40 50) unset num echo ${num[@]} num=(10 20 30 40 50) unset num[2] unset num[3]
例:
九、数组追加元素
方法一
[root@localhost ~]# num=(10 20 30 40 50 60) [root@localhost ~]# echo ${num[@]} 10 20 30 40 50 60 [root@localhost ~]# num[6]=70 [root@localhost ~]# echo ${num[@]} 10 20 30 40 50 60 70
例:
方法二
[root@localhost ~]# num=(10 20 30 40 50 60 70) [root@localhost ~]# num[${#num[@]}]=80 [root@localhost ~]# echo ${num[@]} 10 20 30 40 50 60 70 80
例:
弊端
方法三
[root@localhost ~]# name=('xiao ming' 'xiao hong' 'xiao gang') [root@localhost ~]# echo ${name[@]} xiao ming xiao hong xiao gang [root@localhost ~]# echo ${#name[@]} 3 [root@localhost ~]# name=("${name[@]}" 'xiao li') [root@localhost ~]# echo ${name[@]} xiao ming xiao hong xiao gang xiao li [root@localhost ~]# echo ${#name[@]} 4
例:
如果不加双引号
如果用*追加
方法四
[root@localhost ~]# name=('xiao ming' 'xiao hong' 'xiao gang') [root@localhost ~]# echo ${name[@]} xiao ming xiao hong xiao gang [root@localhost ~]# echo ${#name[@]} 3 [root@localhost ~]# name+=('zxc' 'abc' 'qwe') [root@localhost ~]# echo ${name[@]} xiao ming xiao hong xiao gang zxc abc qwe [root@localhost ~]# echo ${#name[@]} 6
例:
十、向函数传数组参数
如果将数组变量作为函数参数,函数只会取数组变量的第一个值。
#!/bin/bash test1() { echo "函数接收到的参数列表为:$@" newarr=($*) echo "新数组的值为:${newarr[@]}" } arr=(10 20 30 40 50) echo "原始数组的值为:${arr[@]}" test1 ${arr[@]}
例:
十一、从函数返回数组
求数组中左右元素的累加和。
#!/bin/bash test1() { echo "函数接收到的参数列表为:$@" newarr=($*) sum=0 for i in ${newarr[@]} do sum=$[$sum + $i] done echo "数组所有元素的累加值为:$sum" } ############# main ############## arr=(10 20 30 40 50) echo "原始数组的值为:${arr[@]}" test1 ${arr[@]}
例:
求把原数组中所有的元素值乘2后生成一个新的数组并输出。
#!/bin/bash test2() { newarr=(`echo $@`) length=${#newarr[@]} for ((i=0; i<$length; i++)) do newarr[$i]=$[${newarr[$i]} *2] done echo ${newarr[@]} } ########## main ########## array=(10 20 30 40 50) echo "原始数组的值为:${array[@]}" result=(test2 ${array[@]}) echo "新数组的值为:${result[@]}"
例:
十二、数组排序算法
类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断的向前移动。
基本思想
冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部.上升到顶部。
算法思路
冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一 般为要排序的数组长度减1次,因为最后一次循环只剩下一 一个数组元素, 不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。
#!/bin/bash a=(20 60 40 30 50 10) echo "原始数组的顺序为:${a[@]}" #获取数组的长度 length=${#a[@]} #外层循环定义比较的轮数,轮数为数组长度减,从1开始 for ((b=1; b<$length; b++)) do #确定比较相邻两个元素的位置,较大往后放,并且每轮比较的最后一个元素下标要递减 #这里使用变量c代表左边比较元素的下标范围 for ((c=0; c<$length-b; c++)) do #定义左边比较的元素的值 left=${a[$c]} #定义右边比较的元素的值 d=$[$c + 1] right=${a[$d]} #如果左边的元素比右边的元素的值大就互换元素的位置 if [ $left -gt $right ];then #把左边元素的值保存到临时变量tmp中 tmp=$left #把右边元素的值赋给左边的元素 a[$c]=$right #再保存在临时变量中的值赋给右边的元素 a[$d]=$tmp fi done done echo "排序后的数组的顺序为:${a[@]}"
例:
与冒泡排序相比,直接选择排序的交换次数更少,所以速度会快些。
基本思想
将指定排序位置与其它数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后-~个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。
#!/bin/bash a=(20 50 40 30 60 10) echo "原始数组的顺序为:${a[@]}" #获取数组的长度 length=${#a[@]} #外层循环定义比较的轮数,轮数为数组长度减1,从1开始 for ((b=1; b<$length; b++)) do #先假设下标为0的元素值最大 index=0 #通过比较获取拥有最大值的下标(索引) for ((c=1; c<=$length-b; c++)) do #定义右边比较的元素的值 right=${a[$c]} #定义左边比较的元素的值 left=${a[$index]} if [ $right -gt $left ];then index=$c fi done #把最大的元素的值跟当前轮次最后一个元素的值进行交换 last=$[$length - $b] tmp=${a[$last]} a[$last]=${a[$index]} a[$index]=$tmp done echo "排序后的数组顺序为:${a[*]}"
例:
以相反的顺序把原有数组的内容重新排序。
基本思想
把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换。
#!/bin/bash a=(1 2 3 4 5 6 7) echo "原数组的顺序为:${a[@]}" #获取数组长度 length=${#a[@]} for ((b=0; b<$length/2; b++)) do #将第一个下标对应的元素赋值给临时变量 tmp=${a[$b]} #将最后一个下标对应的元素赋值给第一个索引 a[$b]=${a[$length-1-$b]} #将第一个索引对应的元素赋值给最后一个索引 a[$length-1-$b]=$tmp done echo "反转排序后的数组顺序为:${a[@]}"
例: