Detailed Explanation of the Loop Structure of Shell Programming Quick Start

8c24851c4f9c4f6dbe0de1a3181800f5.png

1. Find the sum of two numbers

sum of integers

The number type of the shell program is only an integer type, and does not support floating point numbers. like:

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:~$

sum of floats 

In shell programming, floating-point numbers can only be used as strings to operate. The script syntax itself does not provide floating-point operation methods, but you can call bc, awk and other external commands to calculate and return the results. like:

hann@HannYang:~$ cat sum2.sh
#!/bin/bash

num1=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

The operation of two or more numbers only needs to list the calculations; but if there is a lot of data to be processed, or the number is unknown in advance, it is necessary to cycle to process repeated operations.

2. Calculate the sum of 1-100

Using the example of accumulation from 1 to 100, illustrate the writing of various statements in the loop structure :

C style for loop

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的值

The difference between while and until

The while loop executes when the condition test is true and exits the loop when it is false
The until loop executes when the condition test is false and exits the loop when it is true

while A; do is equivalent to until not A; do
until A; do is equivalent to while not A; do

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

The difference between break and continue 

The break statement is used to exit the current loop. When the break is executed, it will immediately jump out of the current loop and execute the subsequent code.
In a multi-level nested loop, break will only jump out of the nearest level of loop.

The continue statement is used to end this loop, skip the remaining code in this loop, and directly enter the next loop.
In a multi-level nested loop, continue will only skip the nearest level of loop.

The basic usage of the two sentences is basically the same as that of other languages, and no other examples are given.

relational operator

-eq equal means ==, check whether two numbers are equal, return true if they are equal.
-ne not equal ie !=, check whether two numbers are not equal, return true if they are not equal.
-gt great than means >, check whether the number on the left is greater than the number on the right, and if so, return true.
-lt less than means <, check whether the number on the left is smaller than the number on the right, and if so, return true.
-ge great equal means >=, check whether the number on the left is greater than or equal to the number on the right, and if so, return true.
-le less equal, namely <=, checks whether the number on the left is less than or equal to the number on the right, and if so, returns true.


3. Ninety-nine multiplication table

Using the example of the ninety-nine multiplication table, show how to write double loops:

C style for double loop 

The single loop has been mentioned above, and the double loop is basically the same as the style of C:

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

output:

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 

The above 2~3 numbers are not aligned. This is the shortcoming of echo, which can be corrected in two cases by using the if conditional statement.

In another way, use the printf command to specify the output format:

#!/bin/bash
for ((i=1;i<=9;i++)); do
	for ((j=1;j<=i;j++)); do
		printf "$j*$i=%2d " $((i*j))
 	done
	echo
done

output: 

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)) can also be written as printf "%d*%d=%2d " $j $i $((i*j))

The printf collection is also similar to the output function printf() of the C language; the result of the first column still has more spaces, so it will not be changed for the time being

for...in double loop

When j>i, continue:

#!/bin/bash
for i in {1..9}; do
	for j in {1..9}; do
		if [ $j -gt $i ];then continue;fi
		printf "$j*$i=%2d " $[i*j]
	done
	echo
done

Implement {1.. $i }  with the eval command

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

eval backticks the string with ``, you can also use: $(eval echo {1..$i}), equivalent.

Implemented with the external command seq

#!/bin/bash
for i in `seq 9`; do
	for j in `seq $i`; do
		printf "$j*$i=%2d " $[i*j]
	done
	echo
done

Usage of seq: Generate a sequence of numbers, which can be considered as an arithmetic sequence:

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.
......

Example:

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

Support "step size" step, placed in the middle of the starting number, format: seq start step end, the three parameters can also be floating point numbers.


over

Guess you like

Origin blog.csdn.net/boysoft2002/article/details/132415638