bash編程初體驗之for

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

wKiom1e9PX6xF5mCAABiKpuqBGQ594.png

當然,如果已經編寫好了判斷文件類型的腳本,還可以直接調用:

#!/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

wKioL1e9P5qAiQp4AABxJ09hzm8826.png

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

wKiom1e9P9axURVbAABCO6T2yJE151.png

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"

wKioL1e9QBLyWfUMAAArqyr6X8Y227.png

當然,也可以這樣:

  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

wKiom1e9QHHzvtv4AAB067Dt7o8438.png

當然,也可以這樣:

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

wKiom1e9QR2DA2tVAABlWL_1Ld0788.png

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

wKiom1e9QajRToIfAABm9UxrFlg301.png

8.打印國際象棋棋盤

國際象棋,就是一個八行八列,兩種顏色相間的一個棋盤,如下圖:

wKiom1e9QcmRT5S3AAGCumVhqLM840.png

思路一:找出每個顏色塊所對應的座標,其所在行記爲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

wKioL1e9ShSyGIumAAAdJN9svHU214.png

思路二代碼:

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

wKiom1e9SkDgcvLFAAAejndWLkk592.png


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"

wKiom1e9TUfiO-K7AAAqL_Ln7i8578.png

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."

wKioL1e9WEngV_DLAACEkwxI-IA570.png

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

wKiom1e9WHKTBq_KAABaq-_XHWo112.png

當然,也可以這樣:

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"

wKiom1e9WKTz3ki4AAA4QAQ3zI8772.png

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

wKioL1e9WPTBuPbhAAAeiUXaCiA117.png

 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

wKioL1e9WZbSdlTLAAAqD7LawhQ519.png


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

wKiom1e9WeGCGUFIAABbCwqXlW8594.png

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"


wKiom1e9Wmai74zdAAAcXJNXQb0277.png

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

wKiom1e9WzbQDPjVAABekKxRZ80547.png


本文其它案例會持續更新......


止戰

2016.8.24


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