Linux shell編程之使用結構化命令 for循環 while循環 until循環 break命令 continue命令詳解

目錄

使用結構化命令 for循環 while循環 until循環 break命令 continue命令

①for循環

for循環基本格式:

讀取值複雜的列表的內容

從變量讀取列表:

從命令讀取值:

更改字段分隔符:

用通配符讀取目錄

for循環實戰——循環處理文件數據

②while循環

while循環的基本格式

③until循環

untill循環的基本格式:

         循環嵌套



 

前言

>>>學習循環的目的:瞭解如何重複一些過程和命令,即爲循環執行一組命令直到某個特定條件

>>>與循環相關的命令主要包括:forwhileuntil

 


 

for循環

>>>bash shell提供了for命令,允許我們創建一個遍歷一系列值的循環

>>>for循環便利的列表假定每個值都是用空格分割的,例如(1 "2" "貝")

>>>當某個值兩邊都是用了雙引號時,shell不會將雙引號當成值的一部分

 

for循環基本格式:

for val in list

do

commands

done

或者 for val in list;do commands;done (常用)

 

關於for循環基本格式說明:

>>>list參數,提供迭代要用到的一系列的值,可以是用空格隔開的字符串,也可以是產生值的命令

>>>for循壞結束後,變量val的值會保留最後一次賦予的值(變量在剩餘shell腳本中依然生效)

          只有unset 變量,變量纔會被清空

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in 0 7 5
do
    echo $val
done
echo "The last val:val=$val"
unset val
echo "After unset val:val=$val"
[bei@localhost test]$ bash for.sh
0
7
5
The last val:val=5
After unset val:val=

       執行完for循環  ,val仍然保留最後一次賦予的值"5",並且在剩餘shell腳本中仍然生效,

       如果需要讓變量val失效,用unset即可

>>>dodone之間可輸入一條或多條shell命令,包括嵌套if語句

[bei@localhost test]$ cat for.sh
#!/bin/bash
count=1
for i in 59 60 99
do
    if [ $i -ge 60 ]                            #在for循環裏嵌套了if語句
    then
        echo "Grade $count : $i"
    fi
    count=$[$count+1]
done
[bei@localhost test]$ bash for.sh
Grade 2 : 60
Grade 3 : 99

 

讀取值複雜的列表的內容

問題:遍歷列表中的值,存在空格或特殊字符

方法:>>>使用 \ 處理

           >>>使用雙引號或單引號處理

案例

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in It's a lucky dog !
do
    echo $val
done
[bei@localhost test]$ bash for.sh
for.sh: line 2: unexpected EOF while looking for matching `''
for.sh: line 6: syntax error: unexpected end of file

>>>列表中存在特殊字符,會報錯

>>>解決方法1:使用\處理

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in It\'s a lucky dog \!
do
    echo $val
done
[bei@localhost test]$ bash for.sh
It's
a
lucky
dog
!

>>>解決方法2:使用雙引號或單引號處理(此方法不僅可以輸出特殊字符,還可以輸出存在空格的值)

>>>shell不會把最外層的引號當做值的一部分,裏面的引號會被輸出

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in "It's" a "lucky dog" "!"
do
    echo $val
done
[bei@localhost test]$ bash for.sh
It's
a
lucky dog                                        #使用引號輸出含有空格的值
!

 

從變量讀取列表:

>>>當列表較長,直接將列表放在for循環中,不美觀,修改麻煩

>>>可以先將列表賦給某個變量,然後再去遍歷變量中的值

案例:

[bei@localhost test]$ cat for.sh
#!/bin/bash
list="1 2 3 4 5"     #將列表賦予變量,然後遍歷變量中的值,實現從變量讀取列表的值
list=$list" 6 7"     #實現列表的拼接
for i in $list
do
    echo $i
done
[bei@localhost test]$ bash for.sh
1
2
3
4
5
6
7

 

從命令讀取值:

使用方法

>>>file="xxx.txt"

>>>for I in `cat $file`                      #使用反引從命令讀取值

案例

[bei@localhost test]$ cat txt
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou
[bei@localhost test]$ cat for.sh
#!/bin/bash
list="./txt"               
for i in `cat $list`
do
    echo $i
done
[bei@localhost test]$ bash for.sh
Guangdong
Guangzhou
Guangdong
Shenzhen
Guangdong
Shantou

 

更改字段分隔符:

>>>上一個案例,從命令讀取值時,txt文件中的內容,行中存在空格,一行中的內容會被分別輸出,不會在同一行輸出

可以通過修改分隔符的方式解決這個問題

什麼是分隔符

>>>分隔符全稱叫內部字段分隔符(internal field separator)

>>>通過環境變量IFS,定義了bash shell字段分隔符的一系列字符

     set |grep IFS

     IFS=$' \t\n'  

>>>默認情況下bash shell的字段分隔符:

     空格( )

     製表符(\t)

     換行符(\n)

>>>如何修改分隔符——可在shell腳本中臨時修改IFS環境變量

[bei@localhost test]$ cat txt
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou
[bei@localhost test]$ cat for.sh
#!/bin/bash
IFS_old=$IFS
IFS=$'\n'
file='txt'
for i in `cat $file`
do
    echo "$i"
done
IFS=$IFS_old
[bei@localhost test]$ bash for.sh
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou

>>>當需要在腳本中臨時修改IFS變量時,需要先將IFS的默認值保存,當臨時IFS變量使用完後,再講IFS恢復成默認值

>>>指定多個分隔符:

     IFS=$' \t\n:;"'          #將空格,製表符,換行符,分號,和雙引號作爲分隔符

 

用通配符讀取目錄

使用通配符/var/history遍歷這個目錄,並對目錄下的文件進行判斷是否爲普通文件

[bei@localhost test]$ cat for.sh
#!/bin/bash
for i in /var/history/*
do
if [ -f "$i" ]
then
echo "$i is exist and is a file"
else
echo "$i is exist and is not a file"
fi
done
[bei@localhost test]$ bash for.sh
/var/history/bei-507.log is exist and is a file
/var/history/root-0.log is exist and is a file

 

for循環實戰——循環處理文件數據

結合的技術:

>>>使用嵌套循環

>>>修改IFS環境變量

案例:處理/etc/passwd文件中的數據,要求逐行遍歷/etc/passwd文件,並將IFS變量的值修改成冒號

[bei@localhost test]$ cat loop.sh 
#!/bin/bash
IFS_OLD=$IFS
IFS=$'\n'
for line in `cat /etc/passwd`
do
        echo "Vales in $line"
        IFS=:
        for value in $line
        do
                echo "$value"
        done
done
IFS=$IFS_OLD
[bei@localhost test]$ bash loop.sh 
Vales in root:x:0:0:root:/root:/bin/bash
root
x
0
0
root
/root
/bin/bash
Vales in bin:x:1:1:bin:/bin:/sbin/nologin
bin
x
1
1	
bin
/bin
/sbin/nologin
Vales in daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon
x
2
2
daemon
/sbin
/sbin/nologin
......

 

 


 

while循環

>>>可以簡單理解,while命令是if-then語句和for循環的混雜體

>>>while命令允許我們定義一個要測試的命令,我們定義的命令若返回的退出狀態碼爲0,就會循環執行一組命令

>>>只要測試條件中的退出狀態碼一直爲0,while命令後面那部分代碼就會一直執行,
直到測試條件中的test命令返回的退出狀態碼不爲0,while命令就會終止執行命令

 

while循環的基本格式

while test command   #測試命令退出狀態碼是0,就會去執行命令other commands

do

other commands

done

說明:

>>>while命令的關鍵是指定的test command返回的退出狀態碼要隨着循環的執行而變化

>>>如果test command的退出狀態碼沒有變化

若一直是0,則會產生一個死循環,other commands會一直被執行

若一直是非0,則other commands一直不會被執行

>>>可以在done後面追加[>> file],會將循環的結果輸出重定向到某個文件

舉例:

[bei@localhost test]$ cat ./txt
[bei@localhost test]$ cat while.sh
#!/bin/bash
val=1
while [ $val -le 3 ]
do
        echo "$val"
        val=$[ $val + 1 ]
done >> ./txt
[bei@localhost test]$ bash while.sh
[bei@localhost test]$ cat ./txt
1
2
3

 

當有多個測試條件時,以最後一個測試條件的退出狀態碼爲準

while test command1 

test command2

test command3 

…….

done

說明

>>>此while循環以test command3的退出狀態碼爲準

>>>test command1和test command2不會影響循環的跳轉

 


 

until循環

>>>until命令和while命令的工作方式,是完全相反的

>>>untile命令允許我們定義一個要測試的命令,我們定義的命令若返回的退出狀態碼爲非0,就會循環執行一組命令

>>>只要測試條件中的退出狀態碼一直爲非0,until命令後面那部分代碼就會一直執行,
直到測試條件中的test命令返回的退出狀態碼爲0,until命令就會終止執行命令

>>>通俗理解:直到until中的測試條件成立,until循環纔會停止

 

untill循環的基本格式:

until test command                        #測試命令退出狀態碼是非0,就會去執行命令other commands

do

other commands

done

 

舉例

[bei@localhost test]$ cat until.sh
#!/bin/bash
val=8
until [ $val -gt 10 ]
do
    echo "$val" 
    val=$[ $val + 1 ]
done
[bei@localhost test]$ bash until.sh
8
9
10

說明:

當val=8時,test命令返回退出狀態碼爲非0,until循環執行do後面的命令

當val=9時,test命令返回退出狀態碼爲非0,until循環執行do後面的命令

當val=10時,test命令返回退出狀態碼爲非0,until循環執行do後面的命令

當val=11時,test命令返回退出狀態碼爲0,until循環不執行後面的命令,循環停止

 


 

循環嵌套

何爲嵌套循環

>>>循環語句可以在循環內部使用任何類型的命令,當循環內使用的是其他循環命令時,這種稱爲嵌套循環

>>>嵌套層次越多,時間複雜度越大,一般來說時間複雜度是乘積關係

案例:

[bei@localhost test]$ cat nested.sh
#!/bin/bash
for (( a=1;a<4;a++ ))
do
    echo "outside loop : $a"
    for (( b=1;b<4;b++ ))
    do
        echo "inside loop : $b"
    done
done
[bei@localhost test]$ bash nested.sh
outside loop : 1
inside loop : 1
inside loop : 2
inside loop : 3
outside loop : 2
inside loop : 1
inside loop : 2
inside loop : 3
outside loop : 3
inside loop : 1
inside loop : 2
inside loop : 3

案例:

[bei@localhost test]$ cat nested.sh
#!/bin/bash
a=1
while [ $a -le 3 ]
do
        b=1
        echo "ouside loop : $a"
        until [ $b -ge 3 ]
        do
                echo "  inside loop : $b"
                b=$[$b+1]
        done
        a=$[$a+1]
done
[bei@localhost test]$ bash nested.sh
ouside loop : 1
        inside loop : 1
        inside loop : 2
ouside loop : 2
        inside loop : 1
        inside loop : 2
ouside loop : 3
        inside loop : 1
        inside loop : 2

 


 

④控制循環

>>>爲何需要控制循環?

當循環啓動時,在不對循環進行控制情況下,就必須等待循環迭代完成後循環才能終止

>>>如何控制循環?

兩個命令可以幫我們控制循環內部的情況: break命令continue命令

 

break命令

>>>退出進行中的循環(包括for循環,while循環和until循環)

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for i in 1 2 3 4 5
do
    if [ $i -le 3 ]
    then
        echo "$i"
    else
        echo "breaking"
        break
    fi
done
[bei@localhost test]$ bash break.sh
1
2
3
breaking

說明:在for循環,當滿足if-then條件時,不執行break命令
          當不滿足條件時,執行break命令,跳出正在處理的循環,即for循環

 

>>>對於嵌套循環,只會跳出和break最接近的循環,不會跳出外面的循環

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for((a=1;a<4;a++))
do
        echo "a=$a"
        for((b=1;b<4;b++))
        do
                if [ $b -lt 3 ]
                then
                        echo "  b=$b"
                else
                        echo "breaking"
                        break
                fi
        done
done
[bei@localhost test]$ bash break.sh
a=1
  b=1
  b=2
breaking
a=2
  b=1
  b=2
breaking
a=3
  b=1
  b=2
breaking

說明:break命令只會跳出最接近它的那一層循環,而不會影響外部的循環

 

>>>對於嵌套循環,若需要停止外部循環,可以使用參數值 break n 即跳出n層循環

其中的n表示跳出循環的層級,默認情況下n的值爲1,即爲跳出當前循環

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for((a=1;a<4;a++))
do
        echo "a=$a"
        for((b=1;b<4;b++))
        do
                if [ $b -lt 3 ]
                then
                        echo "  b=$b"
                else
                        echo "breaking"
                        break 2
                fi
        done
done
[bei@localhost test]$ bash break.sh
a=1
  b=1
  b=2
breaking

說明:break命令的2意味着它是跳出兩層循環,即外面那層循環也停止了

 

continue命令

>>>只會跳過這一次循環後面部分代碼,但並不完全終止整個循環

案例

[bei@localhost test]$ cat continue.sh
#!/bin/bash
for((a=1;a<=2;a++))
do
        echo "a=$a"
        for((b=1;b<=3;b++))
        do
                if [ $b -ne 2 ]
                then
                        echo "  b=$b"
                else
                        continue
                        echo "command1"
                fi
                echo "command2"
        done
done
[bei@localhost test]$ bash continue.sh
a=1
  b=1
command2
  b=3
command2
a=2
  b=1
command2
  b=3
command2

說明:當b=1時,正常輸出

  當b=2時,執行continue命令,跳過這一次循環後面部分命令,包括command1和command2
                   但for循環未停止

  當b=3時,由於循環未停止,正常輸出

 

 


 

說明:

>>>以上內容是本人學習的總結

>>>如還有錯誤,請留言,指正

>>>亦可分享自己的想法,互相學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章