函数与数组

一、函数

1、函数的概念

定义:将命令序列按照格式写在一起。

作用:方便重复使用。

函数库,集中在一起,随时可以传参使用,大的工程分割成若干个小的功能模块,提供代码的可读性

函数格式:

第一种

function 定义的方法名{

命令序列

}

第二种

定义的方法名(){ 命令序列 }定义名(调用传参)

2、返回码

复制代码
function abc {

num=$(($a*2))
return $num
}
a=10
abc
echo $?
#这里的$?不在具有判断执行结果,只是一个函数内部的返回值

return只能写在函数内部

目的:从函数的内部获取一个返回值,用来判断是否继续执行下一个脚本

在使用return传返回码的时候,默认0是成功,非0都是失败,返回码的值0-255之间,超过了会除256取余数,可以自定义

复制代码
function abc {
read -p "数"  a
if [[ $a -eq $a ]] &> /dev/null
then
num=$(($a*2))
return 0
else
echo "输入错误"
return 1
fi
}
abc

 if [[ $? -eq 0 ]]
then
echo  ok
else
echo no
fi

3、 函数的传参方式已经函数变量的作用范围

1、传参方式

复制代码
定义值
abc () {
num=$(($a+$b))
echo $num
}
read -p "第一个" a
read -p "第二个" b

abc
~ 
第二种方式
abc () {
num=$(($1+$2))
echo $num
}
abc $1 $2

2、函数变量的作用范围

复制代码
abc () {
a=4
b=4
}
a=2
b=9
abc
ehco $a
echo $b
在函数内部定义了全局变量,
外部的赋值是不能改变内部函数的全局变量的

输出结果
a=4
b=4



abc () {
local a=4
local b=4
c=10
}
a=2
b=9
c=1
abc
echo $a
echo $b
echo $c
加了local之后就是函数内部的变量,而不是全局变量,外部的赋值会替换内部的变量值
输出
a=2
b=9
c=10

函数递归:函数调用自己本身的函数

实例:用函数递归的方式实现阶乘

复制代码
abc () {
if [[ $1 -eq 1 ]]
then
 echo 1
else
 local temp=$(($1-1))
 local result=$(abc $temp)
 echo "$(($1*$result))"
fi
}
read -p "请输入你要计算的数字:" num
result1=`abc $num`  #``将运算出来的结果作为一个字符串进行输出
echo $result1

实例:用函数递归的方式实现递归目录到没有文件为止

复制代码
递归目录,直到目录里面没有文件为止
jiecheng () {
for file in `ls $1`
do
#-d 测试目录
if [[ -d  "$1/$file"  ]]
then
  echo $file
  jiecheng "$1/$file"
else
 echo "不是一个目录$file"

fi
done
}
jiecheng $1

4、函数库

函数库中只包含定义的函数,由另外一个脚本传入参数来调用我们定义的函数

实例:小数+整数都可以运算 小数点后两位

函数库文件名hans3.sh

复制代码
jiafa () {
result=$(echo "$1 + $2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
jianfa () {
result=$(echo "$1-$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
chengfa () {
result=$(echo "$1*$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
chufa () {
if [[ $2 -eq 0 ]]
then
 echo "除数不能为0"
else
result=$(echo " $1/$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}

调用函数 文件名diaoyong3.sh

复制代码
. /opt/hanshu3.sh
read -p "输入第一个数:" num1
read -p "输入第一个数:" num2
sum=`jiafa $num1 $num2`
sub=`jianfa $num1 $num2`
mult=`chengfa $num1 $num2`
div=`chufa $num1 $num2`
echo $sum
echo $sub
echo $mult
echo $div

运行调用函数前需要给函数库赋可执行权限

二、数组

1、数组的概念

数组:在集合当中指定多个元素,元素的类型:整数,字符串,可以是浮点

作用:一次性定义多个元素,可以位变量赋值提供便利

数组的定义方法:

数组名=(元素值) 数组名不能重复

数组名=(a b c d)

打印数组值echo {数组名\[\* \]}或者echo {数组名[@]}

复制代码
#两种定义的方法
[root@localhost opt]# test1=(a b c d)
[root@localhost opt]# echo ${test1[*]}
a b c d
#[0]中的0表示下标,从0开始
[root@localhost opt]# test[0]=1
[root@localhost opt]# test[1]=2
[root@localhost opt]# test[2]=3
[root@localhost opt]# echo ${test[*]}
1 2 3

数组的长度指的是数组内包含了几个元素

echo {#test\[\*\]} 或者echo {#test[@]}

复制代码
#test内包含了3个文件
[root@localhost opt]# echo ${#test[*]}
3

查看数组第几个内容

复制代码
[root@localhost opt]# test3=(11 22 33)
[root@localhost opt]# echo ${test3[0]}
11
[root@localhost opt]# echo ${test3[1]}
22
[root@localhost opt]# echo ${test3[2]}
33

对数组进行遍历

复制代码
#对数组进行遍历
test4=(aa bb cc dd)
for i in ${test4[*]}
do
echo $i
done

结果

复制代码
[root@localhost opt]# sh shuzu1.sh 
aa
bb
cc
dd

对数组进行切片

复制代码
[root@localhost opt]# test5=(1 2 3 4 5)
#0表示起始位置,2表示步长,起始位置0开始,包括0移动2个
[root@localhost opt]# echo ${test5[*]:0:2}
1 2
[root@localhost opt]# echo ${test5[*]:1:3}
2 3 4

[root@localhost opt]# echo ${test1[*]}
a b c d
[root@localhost opt]# echo ${test1[*]:1:1}
b
[root@localhost opt]# echo ${test1[*]:1:2}
b c

2、数组替换

临时替换,不会真正改变数组值

复制代码
[root@localhost opt]# echo ${test5[*]/1/a}
a 2 3 4 5
[root@localhost opt]# echo ${test5[*]}
1 2 3 4 5

永久修改,通过修改元素下标的值可以实现

复制代码
[root@localhost opt]# test5[0]=b
[root@localhost opt]# echo ${test5[*]}
b 2 3 4 5
[root@localhost opt]# test5[4]=e
[root@localhost opt]# echo ${test5[*]}
b 2 3 4 e

3、删除数组

删除整个数组

复制代码
[root@localhost opt]# unset test1
[root@localhost opt]# echo ${test1[*]}

[root@localhost opt]# 

删除数组中的元素,元素下标的值不会发生变化

复制代码
[root@localhost opt]# unset test5[0]
[root@localhost opt]# echo ${test5[*]}
2 3 4 e
[root@localhost opt]# echo ${test5[0]}

[root@localhost opt]# echo ${test5[1]}
2

4、数组中进行追加

复制代码
#根据元素下标,指定追加
[root@localhost opt]# echo ${test5[*]}
2 3 4 e
[root@localhost opt]# test5[0]=a
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e
[root@localhost opt]# test5[6]=9
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9

#自动追加

[root@localhost opt]# test5+=(qq oo)
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9 qq oo

#追加只能在最后开始追加,中间缺失的部分不会补齐
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9 qq oo
[root@localhost opt]# unset test5[4]
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 9 qq oo
[root@localhost opt]# test5+=(ddd)
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 9 qq oo ddd
[root@localhost opt]# echo ${test5[4]}

实例:定义一个数组,元素都是整数,实现数字内整数的累加求和

复制代码
sum=0
test1=(10 20 30 40 50)
for i in ${test1[*]}
do
sum=$(($sum+$i))
done
echo $sum

实例:定义一个数组,元素都是整数,分别求出偶数,奇数累加求和

复制代码
sum1=0
sum2=0
test1=(10 15  40 61 31 42)
for i in ${test1[*]}
do
if [[ $((i%2)) -eq 0 ]]
then
sum1=$(($sum1+$i))
else
sum2=$(($sum2+$i))
fi
done
echo "偶数的和为:$sum1"
echo "奇数的和为:$sum2"
运行结果
[root@localhost opt]# sh shuzu2.sh
偶数的和为:92
奇数的和为:107

实例:定义一个数组,并取出一个最小值,最大值

复制代码
test1=(3 5 7 4 1)
max=${test1[0]}
min=${test1[0]}
for i in ${test1[*]}
do
if [[ $i -gt $max ]]
then
 max=$i
fi
if [[ $i -lt $min ]]
then
 min=$i
fi
done
echo "max=$max"
echo "min=$min"

结果

复制代码
[root@localhost opt]# sh shuzu2.sh
max=7
min=1

5、冒泡排序

冒泡排序类似于气泡上涌的工作,会将数组当中的元素按照从小到大,或者从大到小的顺序进行一个重新排列

从小到大排

思路:对比两个相邻的元素,以从下到大为例,满足交换条件的元素,小的往左移,大的往右移动

数组的位置发生变化(下标对应的元素的值发生变化)

双层循环,外部循环控制排序的轮次,内部循环用来对比两个元素的大小,决定是否互换位置

对比和交换的次数随着排序轮次而减少

实例:使用冒泡排序将test1的内容进行从小到大进行排序

复制代码
test1=(20 10 60 40 50 30)
len=${#test1[*]}
#定义排序的轮次
for ((i=1;i<$len;i++))
do
 for ((k=0;k<$len-i;k++))
 do
#定义第一个数组的值
 first=${test1[$k]}
 j=$(($k+1))
#定义第二个下标位置
 second=${test1[$j]}
 if [ $first -gt $second ]
 then
#交换位置
 temp=$first
 test1[$k]=$second
 test1[$j]=$temp
fi
 done
echo "排序后的数组值为:${test1[*]}"
done  

实例:使用冒泡排序将df的已用进行从大到小进行排序

复制代码
# 取出已用并将%去掉
test1=($(df -h | awk 'NR>1 {print $5}' | tr -d '%'))
len=${#test1[*]}
#定义排序的轮次
for ((i=1;i<$len;i++))
do
 for ((k=0;k<$len-i;k++))
 do
#定义第一个下标的值
 first=${test1[$k]}
 j=$(($k+1))
#定义第二个下标位置
 second=${test1[$j]}
 if [ $first -le $second ]
 then
#交换位置
 temp=$first
 test1[$k]=$second
 test1[$j]=$temp
fi
 done
done
echo "排序后的数组值为:${test1[*]}"
相关推荐
岚天start30 分钟前
解决方案—K8S集群的日志按天并按照命名空间分类定时同步到日志服务器
服务器·docker·kubernetes·shell·日志备份
佐杰1 小时前
什么是DevOps
运维·devops
CaracalTiger1 小时前
本地部署 Stable Diffusion3.5!cpolar让远程访问很简单!
java·linux·运维·开发语言·python·微信·stable diffusion
ai_xiaogui1 小时前
AIStarter跨平台完工:Win/Mac/Linux一键部署Stable Diffusion
linux·macos·stable diffusion·aistarter·kritaai·跨平台部署
顾安r1 小时前
11.10 脚本算法 五子棋 「重要」
服务器·前端·javascript·游戏·flask
梁萌2 小时前
linux中使用docker安装MySQL
linux·运维·docker·容器·mysql安装
文言一心2 小时前
SenseVoice 离线部署指南(Xinference Docker v1.12)
运维·docker·ai·容器
AIchiNiurou2 小时前
mermaid install for free docker
运维·docker·容器
wei_shuo2 小时前
智能运维×低资源占用:金仓数据库助力能源企业降本增效与国产化替换实践
运维·数据库·king base
❀͜͡傀儡师2 小时前
根据docker服务保存日志脚本,时间可选版本
运维·docker·容器