『忘了再學』Shell流程式控制制 — 36、for循環介紹
- 2022 年 6 月 21 日
- 筆記
- 高級測試技能 - Shell基礎
1、for循環介紹
for
循環是固定循環,也就是在循環時已經知道需要進行幾次的循環,有時也把for
循環稱為計數循環。
在Shell中for
循環的語法有如下兩種:
# 語法1:
for 變數 in 值1 值2 值3 …
do
程式
done
這種語法中for
循環的次數,取決於in
後面值的個數(空格分隔),有幾個值就循環幾次,並且每次循環都把該值賦予變數。也就是說,假設in
後面有三個值,for
會循環三次,第一次循環會把值1賦予變數,第二次循環會把值2賦予變數,以此類推。
# 語法2:
for((初始值;循環控制條件;變數變化))
do
程式
done
語法二中需要注意:
- 初始值:在循環開始時,需要給某個變數賦予初始值,如
i=1
; - 循環控制條件:用於指定變數循環的次數,如
i<=100
,則只要i的值小於等於100,循環就會繼續; - 變數變化:每次循環之後,變數該如何變化,如
i=i+1
,代表每次循環之後,變數i
的值都加1。
2、示例
語法一舉例:
需求:列印時間。
# 創建腳本文件
[root@localhost ~]# vim sh/for.sh
#!/bin/bash
for time in morning noon afternoon evening
do
echo "This time is $time!"
done
執行腳本結果:
[root@localhost tmp]# chmod 755 for1.sh
[root@localhost tmp]# ./for1.sh
This time is morning!
This time is noon!
This time is afternoon!
This time is evening!
語法二舉例:
語法二就和其他語言中的for
循環類似了,也就是事先決定循環次數的固定循環了。
需求:從1加到100。
#!/bin/bash
# 定義一個求和變數sum
sum=0
# 定義循環100次
# 在Shell中如果要進行數學運算,需要用雙小括弧括起來,才識別括弧裡面是數值運算。
for((i=1;i<=100;i=i+1))
do
# 每次循環給變數sum賦值
sum=$(($sum+$i))
done
# 輸出1加到100的和
echo "The sum of 1+2+...+100 is :$sum"
3、for循環總結
- 第一種格式的
for
循環是最常見的Shell循環方式。 - 第二種格式的
for
循環適合做數學運算,可以方便的指定循環次數。
4、練習:批量解壓縮腳本
方式一:批量解壓縮
# 創建腳本文件auto-tar.sh
[root@localhost ~]# vim sh/auto-tar.sh
# 批量解壓縮腳本
#!/bin/bash
# 進入壓縮包目錄。
cd /tmp/sh/tar
# 把tar目錄中的所有壓縮包的文件名,保存到tar.log文件中。
# 單>是覆蓋。
# 而且tar.log中內容是每一個文件名是一行。
ls *.tar.gz>tar.log
# 把tar目錄中.tgz類型的壓縮包的名字也追加到tar.log文件中。
# 雙>>是追加。
ls *.tgz>>tar.log &>/dev/null
# 提示:用上面的方式,把需要解壓的所有類型的壓縮文件的名稱,都存入到tar.log文件中。
# 讀取tar.log文件的內容,文件中有多少個值,就會循環多少次,
# 每次循環把文件名賦予變數i
for i in $(cat tar.log)
do
# 解壓縮,並把所有輸出都丟棄
tar -zxvf $i &>/dev/null
# 注意如果還有其他格式的壓縮包,需要在這裡進行if判斷,
# 分別針對不同格式的壓縮文件進行解壓。
# 方式二也一樣。
done
# 刪除臨時文件tar.log,因為腳本執行完就沒有作用了。
rm -rf /tmp/sh/tar/tar.log
說明:
第一種方式的for
循環,in
後有幾個值,就循環幾次,值之間要有空格分隔。
而tar.log
文件中存放的是6個壓縮包的文件名,且每一個文件名佔一行,
[root@localhost tmp]# cat tar.log
apr-1.4.6.tar.gz
apr-util-1.4.1.tar.gz
httpd-2.4.7.tar.gz I
mysq1-5.5.23.tar.gz
php-5.6.15.tar.gz
phpMyAdmin-4.1.4-al1-languages.tar.gz
這樣的格式,就相當於一行算一個值,這樣就可以循環6次,每次的值就是一個壓縮包的文件名,
這樣就完成了所需文件的批量解壓縮。
方式二:批量解壓縮
用for
循環的第二種方式進行批量解壓縮,有兩個需要注意的內容。
- 第一:需要知道壓縮包的總個數,因為我需要用
for
循環的第二種格式進行批量解壓,就需要先知道要循環幾次。
解決方式:把所有需要解壓文件的文件名保存到一個文件中(臨時文件),這時候所需解壓縮文件的文件名就變成了字元串,然後通過wc
命令進行統計就可以。 - 第二:需要把每個壓縮包的名稱提取出來,賦值在變數中。
就是第一次循環,變數中賦值的是第一個壓縮包的文件名,第二次循環,變數中賦值第二個壓縮包的文件名,然後就能夠用tar
命令解壓該壓縮包了。
#/bin/bash
# 進入壓縮包目錄。
cd /tmp/sh/tar
# 把tar目錄中的所有壓縮包的文件名,保存到tar.log文件中。
# 單>是覆蓋。
# 而且tar.log中內容是每一個文件名是一行。
ls *.tar.gz>tar.log
# 把tar目錄中.tgz類型的壓縮包的名字也追加到tar.log文件中。
# 雙>>是追加。
ls *.tgz>>tar.log &>/dev/null
# 提示:用上面的方式,把需要解壓的所有類型的壓縮文件的名稱,都存入到tar.log文件中。
# wc -l命令統計行號,也就是獲取文件個數。
num=$(cat /tmp/sh/tar/tar.log | wc -l) #或者:wc -l /tmp/sh/tar/tar.log
# 開始遍歷解壓文件
for((i=1;i<="$num";i=i+1))
do
# 用awk命令提取文件名,來獲取解壓文件的文件名
# NR是awk的內置變數,表示當前awk所處理的行,是總數據的第幾行。
# 注意'$i'這個地方,依然要使用單引號,使用雙引號會報錯。
# awk 'NR=='$i' {print $1} 意思是獲取第幾行的第幾列資訊。
filename=$(cat tar.log | awk 'NR=='$i' {print $1})
# 解壓文件
tar -zxvf $filename -C /tmp/sh/tar
done
# 刪除臨時文件tar.log
rm -rf /tmp/sh/tar/tar.log
總結:
for
循環的第一種方式,適合作為Shell腳本的編寫,更為簡單。