shell script -- loop control

Fundamentals of shell programming (shell script learning notes)

loop

In Shell programming, it is often necessary to repeatedly execute one or a group of commands, such as printing 10 "Hello World" continuously - although writing 10 echo "Hello World" instead of loop can also complete the same work, but what if printing 100? At this time, if you still use this writing method, it may annoy you. At this time, you have to rely on circulation. Loops in Shell mainly include for, while, until and select.

1. for loop

For loop is the most common loop structure in Shell. According to writing habits, it is divided into list for loop, for loop without list and C-like for loop.

(1) for loop with list

The for loop with list is used to execute a certain number of loops (the number of loops is equal to the number of list elements). Its syntax structure is as follows:

for VARIABLE in (list)
do
        command
done

There are many forms of lists. If the list is a number, it is convenient to enumerate a few numbers one by one. However, if it is 1 to 100, this is not practical. Shell provides a method for counting, for example:

[root@localhost ~]# cat list_number1.sh
#!/bin/bash
for VAR in {1..5}
do
     echo "Loop $VAR times"
done
# perhaps
[root@localhost ~]# cat list_number2.sh
#!/bin/bash
sum=0
for VAR in `seq 1 100`
#for VAR in $(seq 1 100)
do
      let "sum+=VAR"
done
echo "Total: $sum"
#Operation results
[root@localhost ~]# bash list_number2.sh
Total: 5050

(2) for loop without list

The structure of a for loop without a list is as follows:

for VARIABLE
do
       command
done

When using a for loop without a list, you need to pass the variable value to the for loop through parameters when running the script.

[root@localhost ~]# cat for_list1.sh
#!/bin/bash
for VARIABLE in $@
do
        echo-n $VARIABLE
done
#Run time pass in parameters
[root@localhost ~]# bash for_list1.sh 1 2 3
1 2 3

(3) for loop of class C

Shell supports for loops of class C. Readers who know C language or C-like language will be very familiar with the structure of (I = 1; I < = 10; I + +). In shell, the syntax structure is as follows:

for ((expression1; expression2; expression3))
do
       command
done

2.while loop

Like for loop, while loop is also a pre run test statement. Compared with for loop, its syntax is simpler. The syntax structure is as follows:

while expression
do
        command
done

First, while will test the return value of expression. If the return value is true, the loop body will be executed. If the return value is false, the loop will not be executed. After the cycle is completed, it will be tested again before entering the next cycle.

The following example uses a class while loop to calculate the sum of 1 to 100 and the odd sum of 1 to 100 at the same time.

[root@localhost ~]# cat while_sum.sh
#!/bin/bash
#sum01 is used to calculate the sum of 1 to 100
#sum02 is used to calculate the odd sum of 1 to 100
sum01=0
sum02=0
i=1
j=1
while [[ "$i" -le "100" ]]
do
        let "sum01+=i"
        let "j=i%2" #Variable j is used to determine the parity of variable i. if it is an odd number, the remainder is 1
        if [[ $j -ne 0 ]]; then
               let "sum02+=i"
        fi
        let "i+=1"
done

echo "sum01=$sum01"
echo "sum02=$sum02"
#Operation results
[root@localhost ~]# bash while_sum.sh
sum01=5050
sum02=2500

Reading files by line is a very classic use of while, which is often used to deal with formatted data. For example, the following file is used to record student information (created by the reader, the content is as follows).

[root@localhost ~]# cat student_info.txt
John    30      Boy
Sue     28      Girl
Wang    25      Boy
Xu      23      Girl

It is not difficult to observe the contents of this document carefully. The first column is the name, the second column is the age, and the third column is the gender. Using the feature that while can read by line, print student information in turn.

[root@localhost ~]# cat while_file.sh
#!/bin/bash
while read LINE
do
        NAME=`echo $LINE | awk '{print $1}'`
        AGE=`echo $LINE | awk '{print $2}'`
        Sex=`echo $LINE | awk '{print $3}'`
        echo "My name is $NAME,I'm $AGE years old,I'm a $Sex"
done < student_info.txt
#Operation results
[root@localhost ~]# bash while_file.sh
My name is John,I'm 30 years old,I'm a Boy
My name is Sue,I'm 28 years old,I'm a Girl
My name is Wang,I'm 25 years old,I'm a Boy
My name is Xu,I'm 23 years old,I'm a Girl

3.until cycle

Until loop is also a pre run test, but until uses the method of testing false values. When the test result is false, it will continue to execute the loop body, and will not stop the loop until the test is true. The syntax is as follows:

until expression
do
       command
done

The following example uses until to calculate both the sum of 1 to 100 and the odd sum of 1 to 100.

[root@localhost ~]# cat until_sum.sh
#!/bin/bash
sum01=0
sum02=0
i=1
until [[ $i-gt 100 ]]
do
       let "sum01+=i"
       let "j=i%2"
       if [[ $j-ne 0 ]]; then
             let "sum02+=i"
       fi
       let "i+=1"
done
echo $sum01
echo $sum02
#Operation results
[root@localhost ~]# bash until01.sh
5050
2500

4.select loop

select is a menu extension loop. Its syntax is very similar to the for loop with list. The basic structure is as follows:

select MENU in (list)
do
       command
done

When the program runs to the select statement, it will automatically generate all the elements in the list into a list that can be selected by 1, 2, 3, etc., and wait for user input. After the user enters and enters, select can judge the input and execute subsequent commands. If the user directly presses the Enter key after waiting for the input cursor, select will not exit, but generate a list again for input.

The following example uses select to confirm the user's input and hand it over to case for processing. After that, different code segments will be executed according to different inputs. The "|" symbol is used in the code to indicate that the effect of selecting Saturday and Sunday is the same.

[root@localhost ~]# cat select_week.sh
#!/bin/bash
select DAY in Mon Tue Wed Thu Fri Sat Sun
do
        case $DAY in
        Mon) echo "Today is Monday";;
        Tue) echo "Today is Tuesday";;
        Wed) echo "Today is Wednesday";;
        Thu) echo "Today is Thursday";;
        Fri) echo "Today is Friday";;
        Sat|Sun) echo "You can have a rest today";;
        *) echo "Unknown input,exit now" && break;;
        esac
done
#Operation results
[root@localhost ~]# bash select_week.sh
1) Mon
2) Tue
3) Wed
4) Thu
5) Fri
6) Sat
7) Sun
#? 1
Today is Monday
#? 6
You can have a rest today
#? 7
You can have a rest today
#? 8
Unknown input,exit now

5. Nested loop

The so-called nested loop means that the loop body in a loop statement is another loop. Nested loops can be used in the for, while, until and select loop statements mentioned earlier. Multi level nesting can be used in nested loops, but it should be noted that excessive nesting will make the program difficult to understand. Therefore, it is not recommended to use multi-level nesting (more than three levels of nesting) except when it is really necessary

The following uses the nested loop of for to print the 99 multiplication table, a classic program.

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

$ bash nesting1.sh
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

6. Cycle control

break statement

Break is used to terminate the current entire loop body. Generally, break is used together with if judgment statements. When the if conditions are met, break is used to terminate the loop.

We can use the break statement to rewrite the above nested loop program (99 multiplication table):

$ cat nesting2.sh
#!/bin/bash
for ((i=1; i<=9; i++))
do
        for ((j=1; j<=9; j++))
        do
                if [[ $j -le $i ]]; then  # j is less than i output
                        let "mult=$i*$j"
                        echo -n "$j*$i=$mult "
                else
                        break  # Stop if j is greater than i
                fi
        done
        echo
done

$ bash nesting2.sh
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

coutinue statement

The continue statement is used to end the current loop and enter the next loop. Unlike break, continue does not terminate the whole current loop body. It just ends the current loop in advance, and the loop body will continue to execute; Break will end the whole loop.

Let's take printing all primes between 1 and 100 as an example:

$ cat continue.sh
#!/bin/bash

for ((i=1; i<=100; i++))
do
        for ((j=2; j<(i/2)+1; j++))
        do
                if !(($i%$j)); then
                        continue 2
                        # 2 represents two-layer cycle
                fi
        done
        echo -n "$i "
done
echo

$ bash continue.sh
1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Keywords: Linux Operation & Maintenance shell bash

Added by chrislead on Wed, 23 Feb 2022 20:04:00 +0200