目錄
使用結構化命令 for循環 while循環 until循環 break命令 continue命令
前言
>>>學習循環的目的:瞭解如何重複一些過程和命令,即爲循環執行一組命令直到某個特定條件
>>>與循環相關的命令主要包括:for、while和until
①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即可
>>>do和done之間可輸入一條或多條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時,由於循環未停止,正常輸出
說明:
>>>以上內容是本人學習的總結
>>>如還有錯誤,請留言,指正
>>>亦可分享自己的想法,互相學習