文章目录
一:shell数组
1.1:数组应用场景
-
获取数组长度
使用for循环获取具体信息,使用下标或索引标记数组中数据的位置
可以存放多种数据,如:整型,长整形,浮点型(单精度,双精度),字符串等
-
获取元素长度
-
遍历元素
-
元素切片
-
元素替换
-
元素删除
-
…
-
注意,忌讳数组越界,
数组下标从0开始算
数组长度从1开始算
长度为4,数组长度表示为1,2,3,4;数组下标表示为0,1,2,3
-
shell中数组是可变长的
1.2:数组定义方法(推荐方法一)
-
方法一:
基本格式 数组名=(value0 value1 value2...)
-
方法二:
基本格式 数组名=([0]=value [1]=value [2]=value...)
例如 ABC=([0]=11 [1]=22 [2]=33...)
-
方法三:数组元素之间使用空格隔开
'把列表的元素赋予给数组' 基本格式 列表名=“value0 value1 value2” 数组名=($列表名)
例如 AAA=“11 22 33...” ABC=($列表名)
-
方法四:
'每个元素单独定义,多用于元素替换' - 基本格式 数组名[0]=“value” 数组名[1]=“value” 数组名[2]=“value” ...
例如 AAA[0]=“11” AAA[1]=“22” AAA[2]=“33” ...
示例:1创建1-100的数组
[root@shell shuzu]# vim number100.sh #!/bin/bash for ((i=0;i<=99;i++)) do arr[$i]=$[$i+1] done echo ${arr[*]} [root@shell shuzu]# sh number100.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
示例2:创建存放1-100的奇数的数组
[root@shell shuzu]# vim jishu.sh #!/bin/bash for ((i=0;i<=50;i++)) do if [ $[2*$i+1] -le 100 ];then arr[$i]=$[2*$i+1] fi done echo ${arr[*]} [root@shell shuzu]# sh jishu.sh 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
示例3:创建任意数字及长度的数组,根据客户需求加入元素
需求分析1:创建任意,考虑用死循环,while true – break
需求分析2:客户有权利继续加入元素,也可以不加入
[root@shell shuzu]# vim renyishuzu.sh #!/bn/bash i=0 while true do read -p "是否插入元素(yes/no):" doing if [ $doing = no ];then break fi read -p "请输入要插入的元素: " key arr[$i]=$key let i++ done echo ${arr[*]} [root@shell shuzu]# sh renyishuzu.sh 是否插入元素(yes/no):yes 请输入要插入的元素: 33 是否插入元素(yes/no):yes 请输入要插入的元素: 22 是否插入元素(yes/no):yes 请输入要插入的元素: 100 是否插入元素(yes/no):no 33 22 100
1.3:数组包括的数据类型与数组操作
1.3.1:数组包括的数据类型
-
数值类型
-
字符类型
- 使用“”或‘’定义
数组只可存放数值或字符
1.3.2:数组操作
-
获取数组长度
基本格式 ${#数组名[@]} ${#数组名[*]} 例如 [root@shell opt]# abc=(10 20 30) [root@shell opt]# echo ${abc[*]} 10 20 30 [root@shell opt]# echo ${#abc[*]} 3
-
读取某下标赋值
基本格式 ${数组名[下标]} 例如 [root@shell opt]# echo ${abc[1]} 20 [root@shell opt]# echo ${abc[0]} 10 [root@shell opt]# echo ${abc[1]} 20 [root@shell opt]# echo ${abc[2]} 30
-
数组遍历
把每个元素执行do-done里面的语句
[root@shell shuzu]# arr=(10 20 3 100) [root@shell shuzu]# for v in ${arr[*]} > do > echo $v > done 10 20 3 100 [root@shell shuzu]# for v in ${arr[*]} > do > echo ${arr[2]} > done 3 3 3 3
1.4:求数组最大值
-
#!/bin/bash for ((i=1;i<=5;i++));do read -p "请输入第$i个数字:" num abc[$i-1]=$num done max=${abc[0]} for ((k=1;k<=${#abc[*]}-1;k++));do if [ $max -lt ${abc[$k]} ];then max=${abc[$k]} fi done echo "最大值是:$max"
[root@shell opt]# chmod +x max.sh [root@shell opt]# ./max.sh 请输入第1个数字:2 请输入第2个数字:3 请输入第3个数字:66 请输入第4个数字:33 请输入第5个数字:111 最大值是:111
1.5:示例
-
第一个需求:把低于60分的元素,改成60分
[root@shell shuzu]# vim score60.sh #!/bin/bash #原始数组 score=(72 88 40 55 90) #遍历数组 for ((i=0;i<${#score[*]};i++));do #判断是否大于60,未满足直接赋予60 if [ ${score[$i]} -lt 60 ];then new[$i]=60 else new[$i]=${score[$i]} fi done echo ${new[*]} [root@shell shuzu]# sh score60.sh 72 88 60 60 90
另外一种方法
[root@shell shuzu]# vim score60.sh #!/bin/bash #原始数组 score=(72 88 40 55 90) #遍历数组 for ((i=0;i<${#score[*]};i++));do #判断是否大于60,未满足直接赋予60 if [ ${score[$i]} -lt 60 ];then score[$i]=60 fi done echo ${score[*]} [root@shell shuzu]# sh score60.sh 72 88 60 60 90
-
第二个需求,求哪个成绩最大
找一个临时变量赋予初始值做对比
[root@shell shuzu]# vim numberzuida.sh #!/bin/bash score=(72 88 40 55 90) tmp=0 for ((i=0;i<${#score[*]};i++)) do #比较大小 if [ ${score[$i]} -gt $tmp ];then tmp=${score[$i]} fi done echo $tmp [root@shell shuzu]# sh numberzuida.sh 90
-
第三个需求:从小到大排序
双层循环要找内外侧循环变量的关系,冒泡排序
第一种方法每个元素和他后面的元素挨个比,大的放后面
[root@shell shuzu]# vim shuzu_paixu.sh
#!/bin/bash
score=(8 10 30 5 20 90 48 50 33)
#外层为依次取的元素
for ((i=0;i<${#score[*]};i++))
do
#内层为外层的元素和它后面的元素进行挨个比较
for ((j=i+1;j<${#score[*]};j++))
do
if [ ${score[$i]} -gt ${score[$j]} ] ; then
tmp=${score[$i]}
score[$i]=${score[$j]}
score[$j]=tmp
fi
done
done
echo ${score[*]}
[root@shell shuzu]# sh shuzu_paixu.sh
5 8 10 20 30 33 48 50 90
第二种方法:取元素个数减一轮循环,每一轮把左右的元素挨个比,大的元素往后放,每一轮的出的最大值往最右边放,后面就不在进行比较
[root@shell shell]# vim paixu.sh
#!/bin/bash
#外层为轮
score=(45 54 80 65 70 69 95)
for ((i=1;i<${#score[*]};i++))
do
#内层为此
for ((j=0;j<${#score[*]}-i;j++))
do
if [ ${score[$j]} -gt ${score[((j+1))]} ];then
tmp=${score[((j+1))]}
score[((j+1))]=${score[$j]}
score[$j]=$tmp
fi
done
done
echo ${score[*]}
[root@shell shell]# sh paixu.sh
45 54 65 69 70 80 95
1.6:数组的操作
-
数组切片
${数组名[@/*]:起始位置:长度}
[root@shell shell]# num=(11 12 33 44 55) [root@shell shell]# echo ${num[*]:1:3} 12 33 44
-
数组替换
${数组名[@/*]/查找字符/替换字符}
[root@shell shell]# echo ${num[*]} 11 12 33 44 55 [root@shell shell]# echo ${num[*]/44/88} '内存中的替换,原来值不替换' 11 12 33 88 55 [root@shell shell]# echo ${num[*]} 11 12 33 44 55 [root@shell shell]# num=(${num[*]/44/88}) '重新定义并替换,是真实的替换原值'
-
数组删除
unset
[root@shell shell]# unset num[3] '删除单个元素' [root@shell shell]# echo ${num[*]} 11 12 33 55 [root@shell shell]# unset num '删除整个数组' [root@shell shell]# echo ${num[*]}
-
示例:把低于60分的删除
常规错误演示,错误在于执行数组下标循环,删除元素,再根据下标取值,容易出问题
[root@shell shell]# vim score61.sh #!/bin/bash score=(72 88 40 55 40 20 30 70 90) #遍历数组 for ((i=0;i<${#score[*]};i++));do #判断是否小于60,未满足直接删除 if [ ${score[$i]} -lt 60 ];then unset score[$i] fi done echo ${score[*]} [root@shell shell]# sh score61.sh 72 88 30 70 90
正确的做法:for循环取数组的值用遍历法,不用下标取值
[root@shell shell]# vim score60.sh #!/bin/bash score=(72 88 40 55 30 20 70 90) i=0 #遍历数组 for v in ${score[*]};do #判断是否小于60,未满足直接删除 if [ $v -lt 60 ];then unset score[$i] fi let i++ done echo ${score[*]} [root@shell shell]# sh score60.sh 72 88 70 90
1.7:shell脚本调试
-
echo 命令
进行断点测试
[root@shell shell]# vim score60.sh #!/bin/bash score=(72 88 40 55 30 20 70 90) i=0 #遍历数组 for v in ${score[*]};do #判断是否小于60,未满足直接删除 if [ $v -lt 60 ];then echo "删除$v" '断点测试' unset score[$i] fi let i++ done echo ${score[*]} shsh
-
bash命令
sh [-nvx] 脚本名
常用选项
-n 不执行
-vx 执行并输出
[root@shell shell]# sh -vx score60.sh #!/bin/bash score=(72 88 40 55 30 20 70 90) + score=(72 88 40 55 30 20 70 90) i=0 + i=0 #遍历数组 for v in ${score[*]};do #判断是否小于60,未满足直接删除 if [ $v -lt 60 ];then echo "删除$v" unset score[$i] fi let i++ done + for v in '${score[*]}' + '[' 72 -lt 60 ']' + let i++ + for v in '${score[*]}' + '[' 88 -lt 60 ']' + let i++ + for v in '${score[*]}' + '[' 40 -lt 60 ']' + echo 删除40 删除40 + unset 'score[2]' + let i++ + for v in '${score[*]}' + '[' 55 -lt 60 ']' + echo 删除55 删除55 + unset 'score[3]' + let i++ + for v in '${score[*]}' + '[' 30 -lt 60 ']' + echo 删除30 删除30 + unset 'score[4]' + let i++ + for v in '${score[*]}' + '[' 20 -lt 60 ']' + echo 删除20 删除20 + unset 'score[5]' + let i++ + for v in '${score[*]}' + '[' 70 -lt 60 ']' + let i++ + for v in '${score[*]}' + '[' 90 -lt 60 ']' + let i++ echo ${score[*]} + echo 72 88 70 90 72 88 70 90
-
set 命令
set -x 开启调节模式
set +x 关闭调节模式
[root@shell shell]# vim score60.sh #!/bin/bash score=(72 88 40 55 30 20 70 90) i=0 #遍历数组 for v in ${score[*]};do #判断是否小于60,未满足直接删除 set -x '开启调节模式' if [ $v -lt 60 ];then #echo "删除$v" unset score[$i] fi set +x '关闭调节模式' let i++ done echo ${score[*]} ~ [root@shell shell]# sh -vx score60.sh #!/bin/bash score=(72 88 40 55 30 20 70 90) + score=(72 88 40 55 30 20 70 90) i=0 + i=0 #遍历数组 for v in ${score[*]};do #判断是否小于60,未满足直接删除 set -x if [ $v -lt 60 ];then #echo "删除$v" unset score[$i] fi set +x let i++ done + for v in '${score[*]}' + set -x + '[' 72 -lt 60 ']' + set +x + '[' 88 -lt 60 ']' + set +x + '[' 40 -lt 60 ']' + unset 'score[2]' + set +x + '[' 55 -lt 60 ']' + unset 'score[3]' + set +x + '[' 30 -lt 60 ']' + unset 'score[4]' + set +x + '[' 20 -lt 60 ']' + unset 'score[5]' + set +x + '[' 70 -lt 60 ']' + set +x + '[' 90 -lt 60 ']' + set +x echo ${score[*]} 72 88 70 90