bash編程初體驗之for
-
for
-
while
-
until
概述
本
文將介紹以for為代表的循環語句在shell 腳本中的應用,常見的循環語句有for, while,
until,作為循環語句,顧名思義,它就是重復地做一件事,直到滿足某一條件而退出;另外,還有兩個循環控制語句continue與break來配合循
環語句,以實現臨時中斷或跳出循環的功能;以下為for, while, until的知識點提煉:
for, while, until 進入條件 for: 列表元素非空 while:條件測試結果為真 until:條件測試結果為假 退出條件 for: 列表元素遍歷完成 while: 條件測試結果為假 until: 條件測試結果為真 循環控制語句: continue: 表示提前結束本輪循環,而直接進入下一輪循環的判斷; break: 提前跳出循環
其
中,for循環有兩種風格,一種給個變量,讓其去遍歷列表;一種是類似C語言的形式,整個循環就是控制變量,當然這個形式的for循環一般都可寫成
while循環;while與until形式是一樣的,只是進入與退出循環的條件相左而已,它們與read語句結合可達到逐行修改某一文件的功能,其實就
是用read以輸入重定向的方式讀取文件的每一行,讓while去遍歷每一行,且滿足某條件時執行相應的語句;當然until也是類似的;
for循環中列表的生成方法:
(1) 直接給出列表 (2) 整數列表: (a) {start..end} (b) $(seq[start [step]] end) (3) 返回列表的命令 $(COMMAND)(4) 使用glob,如:*.sh (5) 變量引用; $@, $* for 變量名 in 列表;do 循環體 done 執行機制: 依次將列表中的元素賦值給“變量名”; 每次賦值后即執行一次循環體; 直到列表中的元素耗盡,循環結束。
關于雙小括號法的for循環
雙小括號方法,即((…))格式,也可以用于算術運算 雙小括號方法也可以使bash Shell實現C語言風格的變量操作,如: [root@centos7 ~]#i=8 [root@centos7 ~]#((i++)) [root@centos7 ~]#echo $i 9 [root@centos7 ~]# for循環的特殊格式:for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))do 循環體 done 控制變量初始化:僅在運行到循環代碼段時執行一次 控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷 亦即: for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done 等價于 (( EXP1 )) while (( EXP2 )); do COMMANDS (( EXP3 ))
while循環:
while CONDITION do 循環體 循環控制變量修正表達式 done CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次做判斷; 條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環; 因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正。
until循環:
until CONDITION; do 循環體 done
循環控制語句:continue
用于循環體中continue [N]:提前結束第N層的本輪循環,而直接進入下一輪判斷;最內層為第1層 while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
循環控制語句:break
用于循環體中break [N]:提前結束第N層循環,最內層為第1層 while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
創建無限循環:
while true; do 循環體 done until false; do 循環體 done
for循環練兵場
1、判斷/var/log目錄下所有文件的類型。
1 #!/bin/bash 2 # 3 4 for filename in /var/log/* 5 do 6 if [ -f $filename ] 7 then 8 echo "Common file." 9 elif [ -d $filename ] 10 then 11 echo "Birectory file." 12 elif [ -L $filename ] 13 then 14 echo "Symlic link file." 15 elif [ -b $filename ] 16 then 17 echo "Block spelic file." 18 elif [ -S $filename ] 19 then 20 echo "Char spelic file." 21 else 22 echo "Unknow file." 23 fi 24 done
當然,如果已經編寫好了判斷文件類型的腳本,還可以直接調用:
#!/bin/bash # # 調用filetype.sh這個腳本 for filename in /var/log/*do echo $filename |./filetype.sh done
2、添加10個用戶user1-user10,密碼同用戶名。
1 #!/bin/bash 2 # 3 while [[ $1 -lt 1 ]] 4 do 5 read -p "Enter a username: " user 6 if [ -n user ] #判斷是否為非空 7 then 8 break 2 9 fi 10 done 11 12 for i in {1..10} 13 do 14 useradd ${user}${i} 15 echo ${user}${i} |passwd --stdin ${user}${i} &> /dev/null 16 echo "Add ${user}${i} finished." 17 done
3、/etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的文件;分別讀取每個文件,以K開頭的文件輸出為文件加stop,以S開頭的文件輸出為文件名加start; “K34filename stop” “S66filename start”
1 #!/bin/bash 2 # 3 for i in `ls /etc/rc.d/rc3.d` 4 do 5 KS_file=`echo $i |cut -c1` 6 7 case $KS_file in 8 K) 9 echo -e "$i\tstop" 10 ;; 11 S) 12 echo -e "$i\tstart" 13 ;; 14 *) 15 echo "Unknow file." 16 ;; 17 esac 18 done
4、寫一個腳本,提示輸入正整數n的值,計算1+2+3+…n的總和。
1 #!/bin/bash 2 # 3 read -p "Please input a integer: " int 4 declare -i sum=0 5 6 for i in $(seq 1 $int) 7 do 8 sum=$[$sum+$i] 9 done 10 echo "sum is $sum"
當然,也可以這樣:
1 #!/bin/bash 2 # 3 read -p "Please input a integer: " int 4 declare -i sum=0 5 6 for ((i=0;i<=$int;i++)) 7 do 8 sum+=$i 9 done 10 echo "sum is $sum"
5、打印九九乘法表
1 #!/bin/bash 2 # 3 4 for j in {1..9} 5 do 6 for i in $(seq 1 $j) 7 do 8 echo -n -e "${i}X${j}=$[$i*$j]\t" 9 done 10 echo 11 done
當然,也可以這樣:
1 #!/bin/bash 2 # 3 # for的特殊用法 4 for ((j=1;j<=9;j++)) 5 do 6 for ((i=1;i<=$j;i++)) 7 do 8 echo -n -e "${i}X${j}=$[$i*$j]\t" 9 done 10 echo 11 done
6.寫一個腳本,提示請輸入網絡地址,如192.168.0.0,判斷輸入的網段中主機在線狀態。
1 #!/bin/bash 2 # 3 read -p "Please input a network address: " ip 4 5 Cutip=$(echo $ip |cut -d. -f1-3). # 此處可按實際網段修改,注意后面要加個. 6 7 if echo $ip |grep -q -E '\<((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{ 2}|2[0-4][0-9]|25[0-5]))\>' &> /dev/null 8 then 9 for ((i=105;i<110;i++)) # i可按實際需求修改,此處只測試5個ip,譬如i=100;i<=255;i++ 10 do 11 if ping -c 1 -W 1 ${Cutip}${i} &> /dev/null 12 then 13 echo "${Cutip}${i} is up" 14 else 15 echo "${Cutip}${i} is down" 16 fi 17 done 18 else 19 echo "$ip is invaild." 20 fi
7.寫個腳本,實現如下字樣
* *** ****** ********
分析:
星號:每行的星號都是從1開始的奇數遞增,如果高當前行為n,則每行的星號個數為:2n-1 空格:如果設總行數為N,則每一行中空格的個數為:N-n
1 #!/bin/bash 2 # 3 read -p "Please input a number: " N # 代表要打印的行數 4 5 if echo $n |grep -E "[0-9]*" &> /dev/null 6 then 7 for n in `seq 1 $N` # n代表當前行 8 do 9 for ((k=(N-n);k>0;k--)) # k代表空格 10 do 11 echo -n " " 12 done 13 for ((s=1;s<=(2*n-1);s++)) # s代表星號 14 do 15 echo -n "*" 16 done 17 echo 18 done 19 else 20 echo "number is invalid." 21 fi
8.打印國際象棋棋盤
國際象棋,就是一個八行八列,兩種顏色相間的一個棋盤,如下圖:
思路一:找出每個顏色塊所對應的坐標,其所在行記為l,其所在列記為n,發現(l+n)%2如果為零,則為一種顏色A,如果(l+n)不為0,則為另一種顏色B;
思路二:奇數行(列)的顏色布局是相同的,偶數行(列)的顏色布局是相同的;其中,奇數行里面,奇數列對應的顏色是A,偶數列對應的顏色是B; 偶數行里面,奇數列對應的顏色是B,偶數表對應的顏色是A.
思路一代碼:
1 #!/bin/bash 2 # 3 for ((l=1;l<=8;l++)) # l為行數 4 do 5 for ((n=1;n<=8;n++)) # n為列數 6 do 7 if [ $[($l+$n)%2] -eq 0 ] 8 then 9 echo -ne "\e[41;1m \e[0m" # 打印時要加參數 -n,即不換行 10 else 11 echo -ne "\e[43;1m \e[0m" 12 fi 13 done 14 echo 15 done
思路二代碼:
1 #!/bin/bash 2 # 3 for ((l=1;l<=8;l++)) # l代表行 4 do 5 if [ $[$l%2] -eq 0 ] 6 then 7 for ((n=1;n<=8;n++)) # n代表列 8 do 9 if [ $[$n%2] -eq 0 ] 10 then 11 echo -ne "\e[45;1m \e[0m" 12 else 13 echo -ne "\e[46;1m \e[0m" 14 fi 15 done 16 else 17 for ((n=1;n<=8;n++)) 18 do 19 if [ $[$n%2] -eq 1 ] 20 then 21 echo -ne "\e[45;1m \e[0m" 22 else 23 echo -ne "\e[46;1m \e[0m" 24 fi 25 done 26 fi 27 echo 28 done
while 練兵場
1、求100以內所有正整數之和
1 #!/bin/bash 2 # 3 4 declare -i sum=0 5 declare -i i=1 6 7 while [ $i -le 100 ] 8 do 9 let sum+=$i 10 let i++11 done12 echo "1-100之和為 $sum"
2、通過ping命令探測10.1.249.1-254范圍內的所有主機的在線狀態,統計在線主機和離線主機各多少
1 #!/bin/bash 2 # 3 read -p "Enter 10.1.249.0網段或ip: " ip 4 5 Cutip=$(echo $ip |cut -d. -f1-3) # 注意此處的變量賦值 6 declare -i i=100 # 此處可按實際需要修改 7 declare -i uphosts=0 8 declare -i downhosts=0 9 10 if echo $ip |grep -q -E '\<((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9][0-9]?|1[0-9]{ 2}|2[0-4][0-9]|25[0-5]))\>' 11 12 then 13 while [ $i -le 110 ]; do # 此處可按實際需要修改 14 pip=$Cutip.$i # 此變量不能定義在while循環之外 15 ping -c 1 -W 1 $pip &> /dev/null 16 17 if [ $? -eq 0 ]; then 18 echo "$pip is up." 19 let uphosts++ 20 else 21 echo "$pip is down." 22 let downhosts++ 23 fi 24 let i++ 25 done 26 fi 27 echo "The online hosts sum is $uphosts." 28 echo "Then downline hosts sum is $downhosts."
3、打印九九乘法表
1 #!/bin/bash 2 # 3 declare -i j=1 4 5 while [ $j -le 9 ] 6 do 7 declare -i i=1 8 while [ $i -le $j ] 9 do 10 echo -n -e "${i}X${j}=$[$i*$j]\t" 11 let i++ 12 done 13 echo 14 let j++ 15 done
當然,也可以這樣:
1 #!/bin/bash 2 # 3 ((j=1)) 4 while ((j<=9)); do 5 ((i=1)) 6 while ((i<=$j)); do 7 echo -en "${i}X${j}=$[$i*$j]\t" 8 ((i++)) 9 done 10 echo 11 ((j++)) 12 done
4、利用變量RANDOM生成10個隨機數字,輸出這個10數字,并顯示其中的最大者和最小者
1 #!/bin/bash 2 # 3 declare -i max=0 4 declare -i min=10 5 ((i=1)) 6 while ((i<=10)); do 7 random=$[$RANDOM%10+1] 8 ((i++)) 9 echo $random 10 [ $min -gt $random ] && min=$random 11 [ $max -lt $random ] && max=$random 12 done 13 14 echo "MAX is $max" 15 echo "MIN is $min"
5、打印國際象棋棋盤
1 #!/bin/bash 2 # 3 declare -i n # n代表行 4 declare -i l # l代表列 5 6 ((n=1)) 7 while ((n<=8)); do 8 ((l=1)) 9 while ((l<=8)); do 10 if [ $[($n+$l)%2] -eq 0 ]; then 11 echo -en "\e[44;1m \e[0m" 12 else 13 echo -en "\e[47;1m \e[0m" 14 fi 15 ((l++)) 16 done 17 echo 18 ((n++)) 19 done
1 #!/bin/bash 2 # 3 declare -i n # n代表行 4 declare -i i # i代表列 5 6 n=1 7 while ((n<=8)); do 8 if [ $[$n%2] -eq 0 ]; then 9 i=1 10 while ((i<=8)); do 11 if [ $[$i%2] -eq 0 ]; then 12 echo -en "\e[47;1m \e[0m" 13 else 14 echo -en "\e[46;1m \e[0m" 15 fi 16 ((i++)) 17 done 18 else 19 i=1 20 while ((i<=8)); do 21 if [ $[$i%2] -eq 1 ]; then 22 echo -en "\e[47;1m \e[0m" 23 else 24 echo -en "\e[46;1m \e[0m" 25 fi 26 ((i++)) 27 done 28 fi 29 ((n++)) 30 echo 31 done
until練兵場
1、打印九九乘法表
1 #!/bin/bash 2 # 3 declare -i j=1 4 5 until [ $j -gt 9 ] 6 do 7 i=1 8 until [ $i -gt $j ] 9 do 10 echo -n -e "${i}X${j}=$[$i*$j]\t" 11 let i++ 12 done 13 echo 14 let j++ 15 done
2、求1-100之和
1 #!/bin/bash 2 # 3 4 declare -i sum=0 5 declare -i i=100 6 7 until [ $i -lt 1 ] 8 do 9 let sum+=$i 10 let i-- 11 done 12 echo "sum is $sum"
3、隨機生成10以內的數字,實現猜字游戲,提示比較大或小,相等則退出。
1 #!/bin/bash 2 # 3 read -p "Please input 1-10之間的整數:" num 4 random=$[$RANDOM%10+1] 5 6 if echo $num |grep -q -E '\<([1-9]|[0]?)\>'; then 7 until [ $num -eq $random ]; do 8 [ $num -gt $random ] && echo "This num is too big,please give a dot." 9 [ $num -lt $random ] && echo "This num is too dot,please give a big." 10 read -p "Please input 1-10之間的整數:" num 11 done 12 13 echo "Congratulations, you guessed right." 14 else 15 echo "num is invalid." 16 fi
本文其它案例會持續更新……
止戰
2016.8.24
原創文章,作者:Liansir,如若轉載,請注明出處:http://www.www58058.com/39741