標籤:
迴圈 shell中的迴圈主要有for,while,untile,select for 1、列表for迴圈 for VARIABLE in (list) do command done 例:迴圈列印john喜歡的水果 for fruit in apple orange banana pear do echo "$fruit is John‘s favorite" done echo "No more fruits." 注意: in裡面可以是任意命令的標準輸出 如: fruits="apple orange banana pear" seq 1 2 100 #產生1到100的奇數數列 ls 1..5 #表示1 2 3 4 5 #!/bin/bash echo ‘變數作為in的參數‘ fruits="apple orange pear" for fruit in ${fruits} do echo $fruit done echo "序列作為in的參數" for var in 1 2 3 4 5 do echo $var done echo "seq產生的序列作為in的參數" #declare -i total=0 total=0 for var in $(seq 1 2 100) do #total+=$var #(( total += var )) #注意算數運算的寫法,一共三種寫法都可以實現賦值 let "total+=var" done echo "1+3+5+...+99 is $total" echo "ls的結果作為in的參數" for var in $(ls) do ls -l $var done 2、不帶列表的for迴圈 for variable do command done 注意:使用不帶列表的for,需要在運行指令碼時通過參數的方式給for傳遞變數值 #for.sh #!/bin/bash for var do echo $var done # . ./for.sh 1 2 3 可讀性差,可以使用[email protected]實現上面的功能 改進: #!/bin/bash for var in [email protected] do echo $var done 3、類Cfor迴圈 for ((expression ;expression2; expression3)) do command done 例: #!/bin/bash for (( i=0; i<10; i++ )) #這裡沒有什麼空格的要求,為了美觀,使用空格 do echo -n "$i " done 4、for的無限迴圈 for((;1;)) do echo done while while expression do command done 例: 1、#輸出1到10的數字序列 #!/bin/bash declare -i count=0 while [[ $count -lt 10 ]] do echo "$count" count+=1 done 2、#求1-100之和 #求1-100之間奇數之和 #!/bin/bash declare -i sum01=0 declare -i sum02=0 declare -i i=1 declare -i j=1 while [[ i -le 100 ]] do sum01+=i; j=i%2; #if [[ $(( i%2 )) -ne 0 ]];then if [[ j -ne 0 ]];then sum02+=i; fi ((i++));#這裡不可一寫$((i++)) done echo $sum01 echo $sum02 3、#猜數字 #!/bin/bash num=8 echo "Input a number in 1 to 10:" #體會read的用法 while read guass do if [[ $guass -eq $num ]];then echo "Right." break else echo "Wrong.Try Again" fi done 4、按行讀取檔案 cat student_info.txt John 30 Boy Sue 28 Girl Wang 25 Boy Xu 23 Girl 解法一: #!/bin/bash while read line do name=`echo $line | cut -d ‘ ‘ -f1` #echo輸出line之後Tab會變成空格,所以使用cut的時候需要指定分割符(-d ‘ ‘) age=`echo $line | cut -d ‘ ‘ -f2` #也可以使用awk awk ‘{print $n}‘,awk的分割符是空格(‘ ‘)或Tab sex=`echo $line | cut -d ‘ ‘ -f3` echo "My name is $name,I‘m $age years old,I‘m a $sex" done < student_info.txt 注意:整個思路是清晰的,重點是怎麼讀取檔案,選用什麼命令處理行。比較而言,指令碼比編輯一個進階語言程式要簡潔很多 解法二: #!/bin/bash cat student_info.txt | while read line do name=`echo $line | cut -d ‘ ‘ -f1` age=`echo $line | cut -d ‘ ‘ -f2` sex=`echo $line | cut -d ‘ ‘ -f3` echo "My name is $name,I‘m $age years old,I‘m a $sex" done 兩種解法功能相同,但是有細微差別。使用重新導向的while只會產生一個shell,而使用管道的指令碼在運行時會產生3個shell,第一個shell是cat(運行很快,導致無法使用ps命令抓到),第二個shell是管道,第三個shell是while 5、無限迴圈 #方法一 while ((1)) do command done #方法二 while true do command done #方法三 while : do command done 例:檢測系統進程, #!/bin/bash while true do ATD_STATUS=`service atd status | grep running` if [[ -z "$ATD_STATUS" ]];then echo "ATD is stopped , try to restart." service atd restart #在指令碼中,如果不需要命令的傳回值,則直接寫命令即可,而不需要用$()命令替換 else echo "ATD is running,wait 5 sec until next check" fi sleep 5 #延遲函數,單位是秒(s) done until 結構: until expression do command done 描述: 運行前測試,測試結果為false時繼續執行,為true時退出 例: #使用until計算1到100的和以及1-100的奇數和 #!/bin/bash declare -i sum01=0 declare -i sum02=0 declare -i i=0 until [[ i -gt 100 ]] do sum01+=i if [[ $[i%2] -ne 0 ]];then sum02+=i fi ((i++)); done echo "sum01=$sum01" echo "sum02=$sum02" until的無限迴圈 until ((0)) do command done until false do command done select迴圈 結構: select Menu in (list) do command done 描述: 菜單擴充迴圈方式,文法和帶列表的for迴圈非常類似 例: 1、判斷使用者的選擇 #!/bin/bash echo "Which car do you prefer?" select car in Benz Audi VolksWagen do break #注意這個break,沒有這個會一直處於選擇狀態 done echo "You chose $car" 註解:select有判斷使用者輸入的功能,所以select經常和case語句合并使用, 2、聯合使用select和case #!/bin/bash select var in Mon Tue Wed Thu Fri Sat Sun do case $var in #case是不需要break語句的 Mon) echo "Today is Monday" break ;; Tue) echo "Today is Tuesday" break;; Wed) echo "Today is Wednesday" break ;; Thu) echo "Today is Thursday" break ;; Fri) echo "Today is Friday" break ;; Sat|Sun) echo "You can have a rest day" break;; *) echo "Unknown input.Try again" ;; esac done 嵌套迴圈 例:列印九九乘法表 #!/bin/bash declare -i i=1; declare -i j=1; declare -i k=0 for (( i = 1; i <= 9; i++ )) do for (( j = 1; j <= i; j++ )) do k=$i+$j #let "k=i+j" echo -ne $j"*"$i"="$k"\t" #echo -ne $j"*"$i"="$(($i+$j))"\t" #echo -ne $j"*"$i"="$[$j*$i]"\t" #這裡看到了多種運算式求值 done echo done 注意: 1、for的類C寫法,不需要$符號,也不需要使用-le之類的 2、echo輸出定位字元,需要使用-e參數,這表示有逸出字元時轉義。沒有-e會原樣輸出而不解釋逸出字元 3、運算式求值 4、自行改編成其他迴圈版本的九九乘法表 擴充:使用sed和awk輸出九九乘法表 #!/bin/bash seq 9 |sed "H;g"|awk -v RS="" ‘{ for(i=1;i<=NF;i++){ j=i*NR; printf("%d*%d=%d\t",i,NR,i*NR); } printf("\n"); }‘ 迴圈控制 break continue 不做詳細介紹,跟進階語言一樣,唯一的區別是break,continue後面可以接數字,表示跳出嵌套層數,和Java中的標籤類似。 例:列印素數 解法一: #!/bin/bash declare -i i=1 declare -i j=2 for (( i = 1; i < 100 ; i++ )) do for (( j = 2; j < i ;j++ )) do if ! (($i%$j));then #注意! 和(())擴充運算之間有空格 break; fi done if [[ $j -eq $i ]];then echo -ne "$i\t" fi done echo 解法二: #!/bin/bash declare -i i=1 declare -i j=2 for (( i = 1; i < 100 ; i++ )) do for (( j = 2; j < i ;j++ )) do if ! (($i%$j));then #注意! 和(())擴充運算之間有空格 continue 2; #continue後面的數字表示跳出的嵌套數 fi done if [[ $j -eq $i ]];then echo -ne "$i\t" fi done echo
shell學習筆記之七(迴圈)