bash 萬用字元擴展完整說明
在 Linux 系統管理與日常開發中,我們經常需要處理大量的檔案。如果每次都要手動輸入完整的檔案名稱,不僅效率低下,也極易出錯。這時,Shell 提供的「萬用字元」(Wildcards)與「模式匹配」(Pattern Matching)功能就顯得尤為重要。許多使用者常將「Shell 擴展」(Shell Expansion)與「正規表示式」(Regular Expressions)混淆,但這兩者在本質上截然不同。本文將深入解析 Bash 中的萬用字元擴展機制,幫助你更精準、高效地操控檔案系統。
核心萬用字元解析
Bash 在執行指令前,會先對命令列進行擴展。萬用字元擴展主要包含三種核心符號:*、? 和 [...]。它們並非由程式(如 ls 或 rm)處理,而是由 Shell 本身解析後,將匹配到的檔案清單傳遞給程式。
1. 星號 *:匹配任意長度字串
星號是最常用的萬用字元,它能匹配零個或多個任意字元。
假設我們在 /tmp 目錄下建立了一些測試檔案:
mkdir -p /tmp/wildcard_test && cd /tmp/wildcard_test
touch file1.txt file2.txt data.csv backup.tar.gz
若要列出所有 .txt 檔案,指令如下:
ls *.txt
輸出結果:
file1.txt file2.txt
這裡的 * 匹配了 file1 和 file2。值得注意的是,如果目錄中沒有符合條件的檔案,Bash 預設會將 *.txt 當作字串 literal 傳遞,導致指令失敗(除非啟用了 nullglob 選項)。
2. 問號 ?:匹配單一任意字元
問號的功能與 * 類似,但它只匹配恰好一個字元。這在需要精確控制檔案名稱長度時非常實用。
例如,我們想找出名稱剛好為五個字元(不含副檔名)的 txt 檔案:
touch abc.txt abcd.txt a.txt
ls ????.txt
輸出結果:
abcd.txt
注意:abc.txt 因為只有三個字元被 ???? 匹配(少一個),而 a.txt 更少,因此不會被列出。abcd.txt 剛好符合四個問號的條件。
3. 方括號 [...]:匹配字元集合
方括號允許我們指定一組特定的字元,只要匹配其中任一字元即可。
若想列出開頭為 a 或 b 的 txt 檔案:
ls [ab]*.txt
輸出結果:
abc.txt abcd.txt file1.txt file2.txt
等等,這裡似乎有誤解? 讓我們修正一下範例,確保邏輯嚴謹。若我們只建立 a_file.txt 和 b_file.txt:
touch a_file.txt b_file.txt c_file.txt
ls [ab]_file.txt
輸出結果:
a_file.txt b_file.txt
此外,方括號內還可以使用範圍表示法,例如 [0-9] 匹配所有數字,[a-z] 匹配所有小寫字母。
進階技巧:排除與巢狀擴展
除了基本的匹配,Bash 還支援更複雜的模式。
排除字元 [^...] 或 [!...]
在方括號內使用 ^ 或 ! 可以排除特定字元。例如,列出所有開頭不是 a 的 txt 檔案:
ls [^a]*.txt
巢狀萬用字元
萬用字元可以組合使用。例如,匹配副檔名為 .tar 且檔名包含 backup 的檔案:
touch backup_2023.tar backup_2024.tar.gz old_backup.tar
ls *backup*.tar
輸出結果:
backup_2023.tar old_backup.tar
注意:backup_2024.tar.gz 不會被列出,因為其副檔名是 .gz,不符合 .tar 的條件。
常見問題與解決方案
Q1: 為什麼我的萬用字元沒有匹配到檔案?
最常見的原因是檔案名稱包含空白或特殊字元。萬用字元擴展在遇到空白時會視為分隔符號,導致錯誤。此外,如果目錄中沒有符合模式的檔案,Bash 會返回錯誤訊息 No match。
解決方案:
- 使用引號保護變數或特殊字元。
- 使用
shopt -s nullglob讓空匹配時返回空清單而非錯誤。 - 使用
find指令作為萬用字元的強大替代品,特別是在處理大量檔案或複雜條件時。
Q2: 萬用字元與正規表示式(Regex)有什麼不同?
這是一個經典的迷思。萬用字元用於檔案名稱匹配,由 Shell 在執行指令前處理;正規表示式用於內容匹配,由指令(如 grep、sed)在執行時處理。
例如,ls *.txt 是 Shell 擴展,而 grep "pattern" file.txt 中的 pattern 是正規表示式。兩者語法規則完全不同,不可混用。
小結
Bash 的萬用字元擴展是提升 Linux 操作效率的關鍵工具。透過熟練掌握 *、? 和 [...] 的組合,你可以快速篩選、複製、移動或刪除檔案。然而,請務必記住,萬用字元僅適用於檔案名稱的匹配,而非內容搜尋。對於更複雜的檔案操作需求,建議結合 find、grep 等工具,以確保指令的穩定性與準確性。在日常工作中,多練習這些基礎語法,將能讓你的命令行操作更加得心應手。