上次已經學習了基礎的結構化命令if語句蜕径,循環(huán)語句也是使用頻率非常高的結構化命令,比如for語句连舍、while語句等。一起來學習吧~
要點一涩哟、for命令
1索赏、基礎格式
#!/bin/bash
for test in one two three four five
do
echo the number is $test
done
如上關于for語句的格式:
-
test
為變量; -
in
后面的系列值為list參數贴彼,以空格隔開潜腻,變量依次迭代;
在循環(huán)結束后器仗,$test變量會在腳本中保持最后一個值(five)融涣。當然童番,除非你修改了它。
- 在 do 和 done 之間為一/多條標準的bash shell命令威鹿;
- 關于寫法剃斧,for 與 do 可以放在一行里,用分號
;
隔開忽你。如下
for test in one two three four five; do
echo the number is $test
done
2幼东、關于list參數
上述舉的例子應該是最簡單的形式:用空格分隔的文本字符串。針對更加實用的情況科雳,list參數也可以是以下的形式
2.1根蟹、儲存變量讀取
#!/bin/bash
list="one two three four five"
for test in $list
do
echo the number is $test
done
- 如上代碼,將系列值儲存在list變量里糟秘,供test迭代简逮。
2.2、文本文件/命令替換讀取
cat number.txt
one
two
three
four
five
- 如上蚌堵,使用
cat
命令準備文本文件
#!/bin/bash
file="number.txt" #將文件引入腳本里的變量
for test in $(cat $file)
do
echo the number is $test
done
- 使用命令替換符
$( )
讀取
2.3买决、字段分隔符
內部字段分隔符(internal field separator)環(huán)境變量為IFS,其默認的分隔符有空格吼畏、制表符督赤、換行符。所以上述例子中有采用空格分隔的;有采用換行符分隔的。
- 但是可能會遇到以下情況:
(1)每行文本里有空格符带饱,但只想根據換行符分隔窗慎,需要重新定義默認分隔符。
cat number1.txt
one two
three
four
five six
#!/bin/bash
IFS=$'\n' #設定分隔符僅為換行符诉位,忽略空格
file="number1.txt"
for test in $(cat $file)
do
echo the number is $test
done
針對上述情況,可以將含有空格的行文字加上雙引號,而不用修改IFS约计。這種解決辦法也適用于文本中本身含有引號的干擾情況。
(2)在腳本里修改環(huán)境變量IFS僅會在腳本中生效迁筛,不影響外部環(huán)境煤蚌。如果在一個腳本中需要在一處更改默認分隔符,而后續(xù)需要沿用原來的默認設置细卧。
IFS.OLD=$IFS
IFS=$'\n'
#
#
#
IFS=$IFS.OLD
(3)在某種情況下尉桩,需要指定多個新的分隔符
IFS=$'\n':;"
- 上述代碼分別指定換行符、冒號贪庙、分號蜘犁,雙引號作為字段分隔符。
此外關于list參數止邮,還有一個技巧:通配符这橙。比如
for file in /home/li/l*
代碼能夠遍歷/home/li/目錄中所有以l開頭的對象奏窑。
3、C語言風格的for命令
#!/bin/bash
for (( a = 1; a < 10; a++ ))
do
echo the number is $a
done
記住第一行特殊格式析恋,賦值可以有空格良哲,條件中的變量不是以美元符開頭。
- 第一部分為原始值助隧;
- 第二部分為循環(huán)條件筑凫;
- 第三部分為迭代過程(遞增/遞減)。
要點二并村、while命令
#!/bin/bash
var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
關于while語句的注意點有:
- while后面的語句判斷后面的命令是命令退出狀態(tài)碼巍实,若返回0(成功執(zhí)行),則繼續(xù)do的命令哩牍;
- do后面的命令一般包括兩部分棚潦。一是執(zhí)行目標命令(循環(huán)的最終目的)
echo $var1
、二是迭代變量值膝昆,var1=$[ $var1 - 1 ]
再次返回給while 進行判斷丸边。直到while后的退出狀態(tài)碼不為0 - done 標志循環(huán)語句結束。
- 值得注意的是在 while后可執(zhí)行目標命令荚孵,但我覺得應該不常見妹窖。
此外還有until語句,與while相反就不探究了(詳見p272)
要點三收叶、嵌套循環(huán)
嵌套循環(huán)就是在迭代中再使用迭代骄呼,命令的執(zhí)行次數為乘積關系。下面以兩個簡單例子了解一下~
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
要點四判没、控制循環(huán)
在循環(huán)條件下蜓萄,有時并非list參數所舉的全部系列值都想采用,也存在只取部分值的情況澄峰。此時需要使用控制循環(huán)命令嫉沽,一般搭配if語句,表明終止循環(huán)的條件俏竞。(我覺得也可以直接修改list參數的值耻蛇。針對具體情況,怎么方便怎么來吧胞此。)
break命令
一旦執(zhí)行,直接終止退出跃捣,不在考慮后面的list參數漱牵。
#!/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"
上述代碼結果中,var1會變到4疚漆;到5時酣胀,因滿足if條件刁赦,執(zhí)行break
命令而終止循環(huán)
continue命令
- 不會直接完全終止,可以設置終止的list參數范圍
#!/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時闻镶,退出碼不為0甚脉;不執(zhí)行then的continue命令,往下執(zhí)行echo語句铆农;
- 若為6牺氨,則執(zhí)行then語句,跳過這一圈剩余的循環(huán)命令墩剖,繼續(xù)下一個for取值7猴凹;
- 取到10時,退出碼不為0岭皂;不執(zhí)行then的continue命令郊霎,往下執(zhí)行echo語句。
關于循環(huán)控制爷绘,也可在嵌套循環(huán)里執(zhí)行
break
或continue
书劝。因為涉及到內循環(huán)、外循環(huán)土至,以及控制命令加不加參數的變化购对,不在贅述了,詳見p277毙籽。
最后以一個實例結束
- 目的:在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
補充一個知識點:在shell腳本中坑赡,可以對循環(huán)的輸出使用管道或進行重定向烙如;直接在done
命令后添加相關命令即可。如下:
done > output.txt
done | sort
參考教材為《Linux命令行與shell腳本編程大全》