Linux學(xué)習(xí)--No.11 腳本結(jié)構(gòu)化命令之循環(huán)語句

上次已經(jīng)學(xué)習(xí)了基礎(chǔ)的結(jié)構(gòu)化命令if語句,循環(huán)語句也是使用頻率非常高的結(jié)構(gòu)化命令,比如for語句、while語句等。一起來學(xué)習(xí)吧~

要點(diǎn)一、for命令

1、基礎(chǔ)格式

#!/bin/bash
for test in one two three four five
do
    echo the number is $test
done

如上關(guān)于for語句的格式:

  • test 為變量;
  • in后面的系列值為list參數(shù),以空格隔開,變量依次迭代;

在循環(huán)結(jié)束后,$test變量會(huì)在腳本中保持最后一個(gè)值(five)。當(dāng)然,除非你修改了它。

  • 在 do 和 done 之間為一/多條標(biāo)準(zhǔn)的bash shell命令;
  • 關(guān)于寫法,for 與 do 可以放在一行里,用分號(hào);隔開。如下
for test in one two three four five; do
    echo the number is $test
done

2、關(guān)于list參數(shù)

上述舉的例子應(yīng)該是最簡(jiǎn)單的形式:用空格分隔的文本字符串。針對(duì)更加實(shí)用的情況,list參數(shù)也可以是以下的形式

2.1、儲(chǔ)存變量讀取

#!/bin/bash
list="one two three four five"
for test in $list
do
    echo the number is $test
done
  • 如上代碼,將系列值儲(chǔ)存在list變量里,供test迭代。

2.2、文本文件/命令替換讀取

cat number.txt
one
two
three
four
five
  • 如上,使用cat命令準(zhǔn)備文本文件
#!/bin/bash
file="number.txt"    #將文件引入腳本里的變量
for test in $(cat $file)
do
    echo the number is $test
done
  • 使用命令替換符$( )讀取

2.3、字段分隔符

內(nèi)部字段分隔符(internal field separator)環(huán)境變量為IFS,其默認(rèn)的分隔符有空格、制表符、換行符。所以上述例子中有采用空格分隔的;有采用換行符分隔的。

  • 但是可能會(huì)遇到以下情況:

(1)每行文本里有空格符,但只想根據(jù)換行符分隔,需要重新定義默認(rèn)分隔符。

cat number1.txt
one two
three
four
five six
#!/bin/bash
IFS=$'\n'   #設(shè)定分隔符僅為換行符,忽略空格
file="number1.txt"
for test in $(cat $file)
do
    echo the number is $test
done

針對(duì)上述情況,可以將含有空格的行文字加上雙引號(hào),而不用修改IFS。這種解決辦法也適用于文本中本身含有引號(hào)的干擾情況。

(2)在腳本里修改環(huán)境變量IFS僅會(huì)在腳本中生效,不影響外部環(huán)境。如果在一個(gè)腳本中需要在一處更改默認(rèn)分隔符,而后續(xù)需要沿用原來的默認(rèn)設(shè)置。

IFS.OLD=$IFS  
IFS=$'\n'
#
#
#
IFS=$IFS.OLD

(3)在某種情況下,需要指定多個(gè)新的分隔符

IFS=$'\n':;"
  • 上述代碼分別指定換行符、冒號(hào)、分號(hào),雙引號(hào)作為字段分隔符。

此外關(guān)于list參數(shù),還有一個(gè)技巧:通配符。比如for file in /home/li/l* 代碼能夠遍歷/home/li/目錄中所有以l開頭的對(duì)象。

3、C語言風(fēng)格的for命令

#!/bin/bash
for (( a = 1; a < 10; a++ ))
do
    echo the number is $a
done 

記住第一行特殊格式,賦值可以有空格,條件中的變量不是以美元符開頭。

  • 第一部分為原始值;
  • 第二部分為循環(huán)條件;
  • 第三部分為迭代過程(遞增/遞減)。

要點(diǎn)二、while命令

#!/bin/bash
var1=10
while [ $var1 -gt 0 ]
do
    echo $var1
    var1=$[ $var1 - 1 ]
done

關(guān)于while語句的注意點(diǎn)有:

  • while后面的語句判斷后面的命令是命令退出狀態(tài)碼,若返回0(成功執(zhí)行),則繼續(xù)do的命令;
  • do后面的命令一般包括兩部分。一是執(zhí)行目標(biāo)命令(循環(huán)的最終目的)echo $var1、二是迭代變量值,var1=$[ $var1 - 1 ] 再次返回給while 進(jìn)行判斷。直到while后的退出狀態(tài)碼不為0
  • done 標(biāo)志循環(huán)語句結(jié)束。
  • 值得注意的是在 while后可執(zhí)行目標(biāo)命令,但我覺得應(yīng)該不常見。

此外還有until語句,與while相反就不探究了(詳見p272)

要點(diǎn)三、嵌套循環(huán)

嵌套循環(huán)就是在迭代中再使用迭代,命令的執(zhí)行次數(shù)為乘積關(guān)系。下面以兩個(gè)簡(jiǎn)單例子了解一下~

for嵌套for

#!/bin/bash
for (( a = 1; a < 3; a++ ))
    echo  "Outer loop $a :"
    for (( b = 1; b <= 3; b++ ))
    do
        echo "  Inside loop: $b"
    done
done

while嵌套for

#!/bin/bash
#
var1=5
#
while [ $var1 -ge 0 ]
do
    echo "Outer loop: $var1"
    for (( var2 = 1; var2 < 3; var2++ ))
    do
        var3=$[ $var1*$var2 ]
        echo "  Inner loop: $var1 * $var2 = $var3"
    done
    var1=$[ $var1 - 1 ]   #在最后交代while變量的迭代
done

要點(diǎn)四、控制循環(huán)

在循環(huán)條件下,有時(shí)并非list參數(shù)所舉的全部系列值都想采用,也存在只取部分值的情況。此時(shí)需要使用控制循環(huán)命令,一般搭配if語句,表明終止循環(huán)的條件。(我覺得也可以直接修改list參數(shù)的值。針對(duì)具體情況,怎么方便怎么來吧。)

break命令

一旦執(zhí)行,直接終止退出,不在考慮后面的list參數(shù)。

#!/bin/bash
for var1 in 1 2 3 4 5 6 7 8 9
do 
    if [ $var1 -eq 5 ]
    then
        break
    fi
    echo "Iteration number: $var1"
done
echo "The for loop is completed"

上述代碼結(jié)果中,var1會(huì)變到4;到5時(shí),因滿足if條件,執(zhí)行break命令而終止循環(huán)

continue命令

  • 不會(huì)直接完全終止,可以設(shè)置終止的list參數(shù)范圍
#!/bin/bash
for (( var1 = 1; var1 < 15; var1++ ))
do
    if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]  
    then
        continue
    fi
    echo "Iteration number: $var1"
done
  • var1值為1時(shí),退出碼不為0;不執(zhí)行then的continue命令,往下執(zhí)行echo語句;
  • 若為6,則執(zhí)行then語句,跳過這一圈剩余的循環(huán)命令,繼續(xù)下一個(gè)for取值7;
  • 取到10時(shí),退出碼不為0;不執(zhí)行then的continue命令,往下執(zhí)行echo語句。

關(guān)于循環(huán)控制,也可在嵌套循環(huán)里執(zhí)行breakcontinue。因?yàn)樯婕暗絻?nèi)循環(huán)、外循環(huán),以及控制命令加不加參數(shù)的變化,不在贅述了,詳見p277。

最后以一個(gè)實(shí)例結(jié)束

  • 目的:在PATH環(huán)境變量中,查找系統(tǒng)有哪些可執(zhí)行文件可供使用。
#!/bin/bash
IFS=:
for folder in $PATH
do
    echo "$folder:"
    for file in $folder/*
    do
        if [ -x $file ]
        then
            echo "  $file"
        fi
    done
done
./test.sh | more

補(bǔ)充一個(gè)知識(shí)點(diǎn):在shell腳本中,可以對(duì)循環(huán)的輸出使用管道或進(jìn)行重定向;直接在done 命令后添加相關(guān)命令即可。如下:
done > output.txt
done | sort


參考教材為《Linux命令行與shell腳本編程大全》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容