首頁 > 軟體

Linux下Shell的for迴圈語句範例

2020-06-16 16:36:04

迴圈不管在程式中還是指令碼中都需要經常用到,在寫shell指令碼時,經常需要for進行100次迴圈。for 迴圈是固定回圈,也就是在迴圈時已經知道需要進行幾次迴圈。有時也把 for 迴圈稱為計數迴圈。

Shell for迴圈語法

for 變數 in 列表
do
    command1
    command2
    ...
    commandN
done

**也可以寫成:for var in list; do

讀取列表中的值

#!/bin/bash
#basic for command

for linuxidc in Linux公社 Linuxmi linux Ubuntu
do
  echo The next state is $linuxidc
done

執行結果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
The next state is Linux公社
The next state is Linuxmi
The next state is linux
The next state is Ubuntu

在最後一次疊代後,$linuxidc變數的值會在shell指令碼的剩餘部分保持有效。它會一直保持最後一次疊代的值(除非你已經修改了它)。

讀取列表中的複雜值

有兩種解決辦法:

*使用跳脫字元(反斜線)來將單引號轉移;

*使用雙引號來定義用到單引號的值。

#!/bin/bash
#basic for command

for linuxidc in Kotlin Linuxmi'com linux Ubuntu "CentOS'rhel" Oracle
do
  echo The next state is $linuxidc
done

執行結果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
The next state is Kotlin
The next state is Linuxmi'com
The next state is linux
The next state is Ubuntu
The next state is CentOS'rhel
The next state is Oracle

*記住,for命令用空格來劃分列表中的每個值。如果在單獨的資料值中有空格,就必須用雙引號將這些值圈起來。

從變數讀取列表

將一系列的值都集中儲存在一個變數中,然後需要遍歷變數中的整個列表。

#!/bin/bash
#using a variable to hold the list

list="Linuxidc Linuxmi Ubuntu Fedora"
#向已有列表中新增或拼接一個值
list=$list" success"
for state in $list
do
  echo "this word  is $state"
done

執行結果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
this word  is Linuxidc
this word  is Linuxmi
this word  is Ubuntu
this word  is Fedora
this word  is success

從命令讀取值

有兩種方式可以將命令輸出賦值給變數:

(1)反引號字元(`)

(2)$()格式

例如:

linuxidc=`date`
linuxidc=$(date)

生成列表中所需值就是使用命令的輸出。

#!/bin/bash
# reading values from a file

file="states"
for state in $(cat $file)
do
  echo "welcome $state"
done

states檔案內容;

www.linuxidc.com
Hello World
Linuxmi com
linuxidc.net Linux公社

執行結果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
welcome www.linuxidc.com
welcome Hello
welcome World
welcome Linuxmi

更改欄位分隔符

造成這個問題的原因是特殊的環境變數IFS,叫作內部欄位分隔符。預設情況下,bash shell會將下列字元當作欄位分隔符:

 *空格

 *製表符

 *換行符

如果bash shell在資料中看到這些字元中的任意一個,它就會假定這表明了列表中一個新資料欄位的開始。

想修改IFS的值,使其只能識別換行符,那就必須:

IFS=$'n'

將這個語句加入到指令碼中,告訴bash shell在資料值中忽略空格和製表符。

#!/bin/bash
# reading values from a file

file="states"
IFS=$'n'
for state in $(cat $file)
do
   echo "Welcome $state"
done

執行結果:

Welcome www.linuxidc.com
Welcome Hello World
Welcome Linuxmi com
Welcome linuxidc.net Linux公社

一個可參考的安全實踐是在改變IFS之前儲存原來的IFS值,之後再恢復它。

實現:

IFS.OLD=$IFS
IFS=$'n'
<在程式碼中使用新的IFS值>
IFS=$IFS.OLD

這就保證了在指令碼的後續操作中使用的是IFS的預設值。

遍歷一個檔案中用冒號分隔的值:

IFS=:

如果要指定多個IFS字元,只要將它們在賦值行串起來就行。

IFS=$'n':;"

這個賦值會將換行符、冒號、分號和雙引號作為欄位分隔符。如何使用IFS字元解析資料沒有任何限制。

用萬用字元讀取目錄

#!/bin/bash
for file in /home/linuxidc/linuxidc.com/*;  
do  
echo $file is file path ! ;  
done

執行結果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
/home/linuxidc/linuxidc.com/03.jpg is file path !
/home/linuxidc/linuxidc.com/123.jpg is file path !
/home/linuxidc/linuxidc.com/123.png is file path !
/home/linuxidc/linuxidc.com/2.avi is file path !
/home/linuxidc/linuxidc.com/amp is file path !
/home/linuxidc/linuxidc.com/atom-amd64.deb is file path !
/home/linuxidc/linuxidc.com/car.jpg is file path !
/home/linuxidc/linuxidc.com/car.png is file path !
/home/linuxidc/linuxidc.com/chenduling.jpg is file path !
/home/linuxidc/linuxidc.com/com.testdemo.java is file path !
/home/linuxidc/linuxidc.com/DarkPicDir is file path !
/home/linuxidc/linuxidc.com/data is file path !

類C風格for迴圈的語法格式

for((expr1; expr2; expr3))  
do  
    command  
    command  
    ...  
done

有些部分並沒有遵循bash shell標準的for命令:
*變數賦值可以有空格
*條件中的變數不以美元符開頭
*疊代過程的算式為用expr命令格式

ex9、輸出前6個正數

#!/bin/bash
#使用類C風格for迴圈輸出1~6  
for ((integer = 1; integer <= 6; integer++))   
do  
    echo "$integer"  
done

執行如下:

儘管可以使用多個變數,但你只能在for迴圈中定義一種條件。

#!/bin/bash
for ((x=1,y=8;x<=8;x++,y--))
do
   echo "$x - $y"
done

執行如下:

使用類C風格for迴圈要注意以下事項:

a.如果迴圈條件最初的退出狀態為非0,則不會執行迴圈體
b.當執行更新語句時,如果迴圈條件的退出狀態永遠為0,則for迴圈將永遠執行下去,從而產生死迴圈
c.Linux shell中不執行使用非整數型別的數作為迴圈變數
d.如果迴圈體中的迴圈條件被忽略,則預設的退出狀態為0
e.在類C風格的for迴圈中,可以將三個語句全部忽略掉,下面是合法的for迴圈

#!/bin/bash
for((; ; ))  
do  
    echo "hello world www.linuxidc.com"  
done

 


IT145.com E-mail:sddin#qq.com