整理各種使用 Bash 迴圈自動處理檔案與目錄相關的指令稿範例。
若要使用 bash shell 的
for
迴圈對多個檔案或目錄進行批次處理,有幾種不同的實作方法,不同的情況會適合不同的方式,以下是各種實際的範例。
直接指定檔案
直接將要處理的檔案清單寫在 bash 指令稿中是最簡單的:
# 直接指定要處理的檔案 for f in file1 file2 file3 do echo "處理檔案:$f" done
這裡的 for
迴圈會將每一個檔案名稱逐一取出,執行迴圈內的 echo
指令,使用者可將這行 echo
指令替換為各種檔案處理用的指令(例如壓縮檔案、更改檔名等),即可開發出各種應用。
亦可將檔案清單儲存在變數中,透過變數指定要處理的檔案:
# 透過變數指定要處理的檔案 FILES="/var/log/syslog /etc/fstab /etc/resolv.conf" for f in $FILES do echo "處理檔案:$f" done
也可以將檔案清單寫在另外一個檔案中,讓 bash 指令稿從該檔案中讀取檔案清單後,逐一處理:
# 從 filelist.txt 讀取檔案清單 while IFS= read -r f do echo "處理檔案:$f" done < filelist.txt
目錄中所有檔案
若要對指定目錄中所有的檔案逐一進行處理,可以這樣寫:
# 對 /etc 目錄中所有檔案逐一處理 for f in /etc/* do if [[ -f $f ]] # 判斷是否為檔案 then echo "處理檔案:$f" else echo "不是檔案:$f" fi done
這裡我們使用一個 if
判斷式區分檔案與目錄,如果要忽略目錄的處理,可以將 else
的部分拿掉。
如果只要處理目錄,可以改成這樣:
# 對 /etc 目錄中所有目錄逐一處理 for f in /etc/* do if [[ -d $f ]] # 判斷是否為目錄 then echo "處理目錄:$f" fi done
對於這種單純的判斷式,也可以改用更簡潔的寫法:
# 對 /etc 目錄中所有目錄逐一處理 for f in /etc/* do [ -d $f ] && echo "處理目錄:$f" done
特定類型檔案
如果要對特定類型的檔案進行批次處理,最常見的就是根據檔案名稱的結尾來篩選:
# 對 /etc 目錄中所有 *.conf 檔案逐一處理 for f in /etc/*.conf do if [[ -f $f ]] # 判斷是否為檔案 then echo "處理檔案:$f" fi done
指令稿參數
如果想讓檔案清單透過指令稿的參數傳入,可以這樣寫:
#!/bin/bash # 從指令稿參數讀取檔案清單 for f in $@ do echo "處理檔案:$f" done
這樣就可以透過指令稿的參數傳入檔案清單:
# 從參數傳入檔案清單
./script.sh file1 file2 file3