数组
定义:在集合当中指定多个元素。元素的类型可以是整数、字符串、浮点类型。
作用:可以一次性地定义多个元素,可以为变量赋值提供便利。
数组的定义方法
数组名=(要定义的元素值,用空格隔开,两边的元素要顶格写)
数组名不能重复
例1:定义数组的方式1
test1=(a b c d)
echo ${test1[*]} #打印数组全部内容
a b c d
echo ${test1[@]} #同上
a b c d
例2:定义数组的方式2
test2[0]=1
test2[1]=2
test2[2]=3
echo ${test2[*]}
1 2 3
echo ${test2[0]} #打印数组指定位置的元素
1
echo ${test2[2]}
3
test2[ ]的[ ]中是对应元素的下标,即元素在数组中的位置,下标从0开始。
数组的长度
数组的长度指的是数组内包含的元素的个数。
例:对上文定义的test2数组,获取它的长度。
echo ${#test2[@]}
3 #长度为3,即数组中有3个元素
也可以用echo ${#test2[*]}获取数组的长度。
数组的遍历方式
提到遍历,自然想到使用循环的方式获取数组的元素。
vim shuzu1.sh
test3=(1 2 3 4 5)
for num in ${test4[*]};do
echo -n $num
done
sh shuzu1.sh
12345
数组的切片
切片:即获取数组当中指定下标位置的元素,一个或者多个。
test4=(1 2 3 4 5)
echo ${test5[*]:0:2} #0表示起始位置,2表示步长
1 2
echo ${test5[*]:1:2}
2 3
echo ${test5[*]:1:3}
2 3 4
数组元素的替换
要替换数组中元素的值
临时替换:不会真正改变数组中元素的值,只是临时生效
echo ${test4[*]/4/99} #数组中的元素4被临时替换成99
1 2 3 99 5
echo ${test4[*]}
1 2 3 4 5
永久替换:真正改变数组中元素的值
test4[3]=99 #永久改变元素
echo ${test4[*]}
1 2 3 99 5
删除数组
删除整个数组
echo ${test1[*]}
a b c d
unset test1 #删除数组
echo ${test1[*]}
#为空
删除数组当中的元素
echo ${test4[*]}
1 2 3 99 5
unset test4[3] #删除数组中下标为3的元素
echo ${test4[*]}
1 2 3 5 #下标为3的元素99被删掉了
echo ${test4[3]} #打印此时数组中下标3处的元素
#为空,后面的元素不会递补到下标3的位置。
数组追加元素
方法1:指定下标位置进行添加
test4[3]=44
echo ${test4[*]}
1 2 3 44 5
test4[5]=6
echo ${test4[*]}
1 2 3 44 5 6
方法2:自动追加
test4+=(7 8)
echo ${test4[*]}
1 2 3 44 5 6 7 8
特别的:自动追加只会在数组的最后一位的下标之后往后追加,而不会自动填入到前面空缺的下标中。
练习
例:对一个数组,输出最大值、最小值
vim shuzu1.sh
test1=(5 3 7 4 9)
max=${test1[0]}
min=${test1[0]}
for i in ${test1[*]};do
if [[ $i -gt $max ]];then
max=$i
elif [[ $i -lt $min ]];then
min=$i
fi
done
echo "最大值$max"
echo "最小值$min"
sh shuzu1.sh
最大值9
最小值3
冒泡排序
类似气泡上涌,会将数组中的元素按照从大到小,或者从小到大的顺序进行排序。
思路:从小到大排列,对比两个相邻的元素,满足交换条件的元素,小的往左移,大的往右移,数组的位置发生变化(下标对应的元素的值发生变化。)
使用双层循环实现功能:外部循环控制排序的轮次,内部循环比较两个元素的大小并决定是否互换位置。对比和交换的次数随着排序轮次而减少。
例:从小到大冒泡排序
vim shuzu2.sh
test1=(20 10 60 40 50 30)
echo "原数组的排序为:${test1[*]}"
length=${#test1[*]}
tmp=0
for ((i=0;i<length;i++));do
for ((j=i+1;j<length;j++));do
if [[ ${test1[$i]} -lt ${test1[$j]} ]];then
continue
else
tmp=${test1[$i]}
test1[$i]=${test1[$j]}
test1[$j]=$tmp
fi
done
done
echo "排序后数组的排序为${test1[*]}"
sh shuzu3.sh
原数组的排序为:20 10 60 40 50 30
排序后数组的排序为:10 20 30 40 50 60
练习:对df -h的结果,将Use%所在列的参数,从大到小排列。
需要使用的命令:
df -h | awk 'NR>1 {print $5}' | tr -d '%'
解释:获取df -h结果的第5列(即已用%所在列)的内容,并去除%,方便比较大小。
shuzu1+=(`df -h | awk 'NR>1 {print $5}' | tr -d '%'`)
df -h
echo "排序前:${shuzu1[*]}"
length=${#shuzu1[*]}
tmp1=0
tmp2=0
for ((i=0;i<length;i++));do
for ((j=i+1;j<length;j++));do
if [[ ${shuzu1[$i]} -gt ${shuzu1[$j]} ]];then
continue
else
tmp1=${shuzu1[$i]}
shuzu1[$i]=${shuzu1[$j]}
shuzu1[$j]=$tmp1
fi
done
done
echo "排序后:${shuzu1[*]}"
sh shuzu4.sh
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 38G 10G 28G 27% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 13M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 179M 836M 18% /boot
/dev/mapper/centos-home 19G 33M 19G 1% /home
tmpfs 378M 8.0K 378M 1% /run/user/42
tmpfs 378M 44K 378M 1% /run/user/0
/dev/sr0 4.3G 4.3G 0 100% /mnt
排序前:27 0 0 1 0 18 1 1 1 100
排序后:100 27 18 1 1 1 1 0 0 0