Shell 编程快速入门 之 循环结构详解

news/2024/10/17 23:24:29/

8c24851c4f9c4f6dbe0de1a3181800f5.png

1. 求两数之和

整数之和

shell程序的数字类型只有整数类型一种,并不支持浮点数。如:

hann@HannYang:~$ cat sum.sh
#!/bin/bash# 读取第一个数
echo "请输入第一个数:"
read a# 读取第二个数
echo "请输入第二个数:"
read b# 计算两个数的和
sum=$(( a + b ))# 输出结果
echo "这两个数的和为:$sum"
hann@HannYang:~$ bash sum.sh
请输入第一个数:
5
请输入第二个数:
3
这两个数的和为:8
hann@HannYang:~$

浮点数之和 

在shell编程中,浮点数只能被用作字符串来操作,脚本语法本身不提供浮点数的操作方法,但可以调用bc, awk等外部命令来计算并返回结果。如:

hann@HannYang:~$ cat sum2.sh
#!/bin/bashnum1=3.14
num2=2.72# 计算和
sum=$(echo "$num1 + $num2" | bc)
echo "$num1 + $num2 = $sum"sum=$(echo $num1 $num2 | awk '{print $1+$2}')
echo "$num1 + $num2 = $sum"
hann@HannYang:~$ bash sum2.sh
3.14 + 2.72 = 5.86
3.14 + 2.72 = 5.86

两个或多个数的运算只有列出算式计算就行了;但要处理的数据比较多,或者数量预先不可知就要循环来处理重复的操作。

2. 计算1-100的和

用1~100累和的例子,示例循环结构的各种语句的写法:

C风格for循环

hann@HannYang:~$ sum=0;for ((i=1; i<=100; i++));do let sum+=i;done;echo $sum

for...in

hann@HannYang:~$ sum=0;for i in {1..100};do let sum+=i;done;echo $sum

while...do

sum=0  # 初始化变量sum为0
i=1  # 初始化计数器i为1
while [ $i -le 100 ]; do  # 当计数器i小于等于100时执行循环体let sum+=i  # 将当前整数累加到sum中i=$((i+1))  # 计数器自增1
done  # 结束循环
echo $sum  # 打印出变量sum的值

until...do

sum=0  # 初始化变量sum为0
i=1  # 初始化计数器i为1
until [ $i -gt 100 ]; do  # 当计数器i大于100时执行循环体let sum+=i  # 将当前整数累加到sum中i=$((i+1))  # 计数器自增1
done  # 结束循环
echo $sum  # 打印出变量sum的值

while和until的区别

while循环是当条件测试为真时执行,为假时退出循环
until循环是当条件测试为假时执行,为真时退出循环

while A; do 等价于 until not A; do
until A; do 等价于 while not A; do

while [ ! $i -gt 100 ]; do  <==> until [ $i -gt 100 ]; do
until [ ! $i -le 100 ]; do  <==> while [ $i -le 100 ]; do

break与continue的区别 

break语句用于退出本层循环,当执行到break会立即跳出当前循环,执行后续代码。
在多层嵌套循环中,break只会跳出最近的一层循环。

continue语句用于结束本次循环,跳过本次循环中剩余的代码,直接进入下一次循环。
在多层嵌套循环中,continue只会跳过最近的一层循环。

两种语句的基本用法与其它语言的基本一样,不另举例说明。

关系运算符

-eq    equal 即 ==,检测两个数是否相等,相等返回 true。
-ne    not equal 即 !=,检测两个数是否不相等,不相等返回 true。
-gt    great than 即 >,检测左边的数是否大于右边的,如果是,则返回 true。
-lt     less than 即 <,检测左边的数是否小于右边的,如果是,则返回 true。
-ge    great equal 即>=,检测左边的数是否大于等于右边的,如果是,则返回 true。
-le    less equal,即<=,检测左边的数是否小于等于右边的,如果是,则返回 true。


3. 九九乘法表

用九九乘法表的例子,展示双重循环的写法:

C风格for双重循环 

上面单循环已讲过,双重循环也就那样与C的风格基本一样:

#!/bin/bash
for ((i=1;i<=9;i++)); dofor ((j=1;j<=i;j++)); doecho -n "$j*$i=$((i*j)) "doneecho
done

输出:

1*1=1 
1*2=2 2*2=4 
1*3=3 2*3=6 3*3=9 
1*4=4 2*4=8 3*4=12 4*4=16 
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 

上面2~3数字没对准,这是echo的缺点,可以用if条件语句分2种情况来校正。

换一个方法,使用printf命令可以指定输出格式:

#!/bin/bash
for ((i=1;i<=9;i++)); dofor ((j=1;j<=i;j++)); doprintf "$j*$i=%2d " $((i*j))doneecho
done

输出: 

1*1= 1 
1*2= 2 2*2= 4 
1*3= 3 2*3= 6 3*3= 9 
1*4= 4 2*4= 8 3*4=12 4*4=16 
1*5= 5 2*5=10 3*5=15 4*5=20 5*5=25 
1*6= 6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 
1*7= 7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 
1*8= 8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 
1*9= 9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81

printf "$j*$i=%2d " $((i*j)) 还能写成 printf "%d*%d=%2d " $j $i $((i*j))

printf集合也和C语言的输出函数printf()比较类似的;第一列结果还是多了空格,暂时不改了

for...in 双重循环

当j>i时,continue:

#!/bin/bash
for i in {1..9}; dofor j in {1..9}; doif [ $j -gt $i ];then continue;fiprintf "$j*$i=%2d " $[i*j]doneecho
done

用eval命令实现 {1..$i

#!/bin/bash
for i in {1..9}; dofor j in `eval echo {1..$i}`; doprintf "$j*$i=%2d " $[i*j]doneecho
done

eval 用``反引号字符串,也可以用: $(eval echo {1..$i}),等价的。

用外部命令seq实现

#!/bin/bash
for i in `seq 9`; dofor j in `seq $i`; doprintf "$j*$i=%2d " $[i*j]doneecho
done

seq的用法:产生一个数字序列,可认定是个等差数列:

hann@HannYang:~$ which seq
/usr/bin/seq
hann@HannYang:~$ seq --help
Usage: seq [OPTION]... LAST
  or:  seq [OPTION]... FIRST LAST
  or:  seq [OPTION]... FIRST INCREMENT LAST
Print numbers from FIRST to LAST, in steps of INCREMENT.

Mandatory arguments to long options are mandatory for short options too.
  -f, --format=FORMAT      use printf style floating-point FORMAT
  -s, --separator=STRING   use STRING to separate numbers (default: \n)
  -w, --equal-width        equalize width by padding with leading zeroes
      --help     display this help and exit
      --version  output version information and exit

If FIRST or INCREMENT is omitted, it defaults to 1.  That is, an
omitted INCREMENT defaults to 1 even when LAST is smaller than FIRST.
The sequence of numbers ends when the sum of the current number and
INCREMENT would become greater than LAST.
FIRST, INCREMENT, and LAST are interpreted as floating point values.
INCREMENT is usually positive if FIRST is smaller than LAST, and
INCREMENT is usually negative if FIRST is greater than LAST.
INCREMENT must not be 0; none of FIRST, INCREMENT and LAST may be NaN.
FORMAT must be suitable for printing one argument of type 'double';
it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed point
decimal numbers with maximum precision PREC, and to %g otherwise.
......

示例:

hann@HannYang:~$ seq 5
1
2
3
4
5
hann@HannYang:~$ seq 0 3
0
1
2
3
hann@HannYang:~$ seq 1 2 7
1
3
5
7
hann@HannYang:~$ seq 0 2 7
0
2
4
6
hann@HannYang:~$ seq -w 8 12
08
09
10
11
12
hann@HannYang:~$ seq 0.5 0.25 2.1
0.50
0.75
1.00
1.25
1.50
1.75
2.00

支持“步长”step,放在起始数字中间的,格式:seq start step end,三个参数还可以是浮点数。



http://www.ppmy.cn/news/1063084.html

相关文章

登录校验-Filter-入门

目录 前言 过滤器&#xff08;Filter&#xff09; 快速入门 步骤 详解 登录校验-Filter 具体代码 运行思路 小结 前言 在前面的文章中&#xff0c;我们已经实现了对于用户登陆成功后&#xff0c;生成并下发令牌返回至前端等功能接口的实现&#xff0c;JWT令牌就是用户…

几个nlp的小任务(抽取式问答)

几个nlp的小任务(抽取式问答) 安装库抽取式问答介绍、SQuAD数据集初始化参数加载、导入数据集查看数据集示例加载tokenizer对长文本处理的演示对答案的位置进行验证整合刚才的步骤对数据集中的数据进行预处理加载微调模型设置args 参数使用数据清洗设置训练函数,开始训练安装…

A股自动交易,自动止盈止损,自动打板

一、前言 炒股的都知道&#xff0c;股市里最难克服的就是人性。开发这个项目的初衷即是想通过机器来克服人性的弱点。因为只要把策略定好&#xff0c;机器会无条件挂单。该止损止损&#xff0c;该止盈止盈。 短线的话卖比买更重要&#xff1a;复盘就会发现&#xff0c;大的亏…

第一百二十五回 dart中List和Map的常见用法

文章目录 概念介绍使用方法初始化相互转换元素操作 经验分享 我们在上一章回中介绍了Flexible组件相关的内容&#xff0c;本章回中将介绍 dart中的List和Map.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在这里介绍的List也叫列表&#xff0c;它表示一组相…

RK3399 开机自启一个shell脚本,一直起不来BUG

开机自启shell脚本如下&#xff1a; diff --git a/device/rockchip/common/sepolicy/file_contexts b/device/rockchip/common/sepolicy/file_contexts index eb6b5e4bb4..0bbe781a7c 100755 --- a/device/rockchip/common/sepolicy/file_contextsb/device/rockchip/common/se…

算法笔记:球树

1 KD树的问题 算法笔记&#xff1a;KD树_UQI-LIUWJ的博客-CSDN博客 在kd树中&#xff0c;导致性能下降的最核心因素是因为kd-tree中被分割的子空间是一个个的超方体&#xff0c;而求最近邻时使用的是欧式距离&#xff08;超球&#xff09;。超方体与超球体相交的可能性是极高…

深度学习4. 循环神经网络 – Recurrent Neural Network | RNN

目录 循环神经网络 – Recurrent Neural Network | RNN 为什么需要 RNN &#xff1f;独特价值是什么&#xff1f; RNN 的基本原理 RNN 的优化算法 RNN 到 LSTM – 长短期记忆网络 从 LSTM 到 GRU RNN 的应用和使用场景 总结 百度百科维基百科 循环神经网络 – Recurre…

字节流概述,及字节流写数据的三种方式

1.IO流概述和分类 如果数据通过记事本打开&#xff0c;我们还可以读懂里面的内容就使用字符流&#xff0c;否则使用字节流。如果不知道使用哪种类型的流&#xff0c;就使用字节流。 2.字节流写数据 创建字节输出流的时候&#xff0c;一共做了三件事情。 调用系统功能创建了文…