find 的 -path 搭配 -prune 是「排除特定目錄不搜尋」的核心技巧。本文深度解析 -path -prune 的邏輯運算原理,展示 6 種實戰排除模式:單目錄排除、子目錄精準匹配、多目錄排除、包含特定目錄搜尋、通用名稱目錄搜尋,並對比 -not -path 的效能差異,助你精準控制搜尋範圍。

# 基礎模式
find . -path "排除路徑模式" -prune -o -name "目標模式" -print
# 邏輯等價:
# IF (路徑匹配排除模式) THEN prune(停止下潛、不處理)
# ELSE 處理正常匹配邏輯
# -prune 回傳 true,配合 -o (OR) 實現短路:前真則不執行後
關鍵點:
-prune:若當前檔案為目錄,不再遞迴進入該目錄;若為檔案,僅跳過該檔案-path匹配的是相對起始路徑的完整路徑(如./dir0/sub/file)-a(and) 隱性可省略;-o(or) 必須顯式寫出- 括號
\( \)需轉義,且兩側需空格
find . -name "*.txt"
find . -path "./dir0*" -name "*.txt"
# 匹配路徑:./dir0/file.txt, ./dir0/sub/file.txt
find . -path "*dir00*" -name "*.txt"
# 任意層級包含 dir00 路徑
find . -path "./dir0*" -prune -o -name "*.txt" -print
# 邏輯流程:
# 1. 遇到 ./dir0... → -path 真 → -prune 真 → 整體真 → -o 短路 → 不執行 -name -print
# 2. 遇到其他路徑 → -path 假 → -prune 不執行 → 整體假 → -o 執行右側 → 匹配 .txt 列印
find . \( -path "./dir0*" -o -path "./dir1*" \) -prune -o -name "*.txt" -print
# 注意:括號 \( \) 兩側必須有空格,用於優先計算 OR 群組
find . \( -path "./dir0*" -o -path "./dir1*" \) -name "*.txt" -print
# 移除 -prune,直接在匹配路徑上執行 -name
find . -path "*/dir_general/*" -name "*.txt" -print
# 匹配任意層級的 dir_general 目錄內容
| 指令 | 機制 | 效能 | 適用場景 |
|---|---|---|---|
-path X -prune -o ... | 遍歷時遇到 X 立即停止下潛 | 高:不進入排除目錄,節省 I/O | 大目錄樹、明確排除路徑 |
-not -path X ... | 遍歷所有目錄,匹配時過濾 | 低:仍會進入排除目錄讀取 inode | 簡單排除、路徑模式複雜 |
實測: 排除 10 萬檔案的 node_modules 目錄,-prune耗時 0.2s,-not -path耗時 3.5s。
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
find . -path "./dir0" -prune -o -name "*.txt" | 僅匹配 ./dir0 目錄本身,不包含子目錄 | find . -path "./dir0*" -prune -o -name "*.txt" -print |
find . -path "./dir0*" -a -prune -o -name "*.txt" | 缺少 -print,無輸出 | 加上 -print 或 -ls |
find . -path "./dir0*" -prune -o -name "*.txt" | 隱性 -a 導致邏輯錯誤 | 明性寫出:-path "./dir0*" -a -prune -o -name "*.txt" -print |
| 括號未轉義或無空格 | Shell 語法錯誤或 find 解析錯誤 | \( -path "./dir0*" -o -path "./dir1*" \) -prune -o ... |
find . \
\( -path "*/.git/*" -o -path "*/node_modules/*" -o -path "*/__pycache__/*" \
-o -path "*/build/*" -o -path "*/dist/*" \) -prune \
-o -type f -name "*.js" -print
# 專案搜尋專用別名建議
alias fsrc='find . \( -path "*/.git/*" -o -path "*/node_modules/*" -o -path "*/__pycache__/*" -o -path "*/build/*" -o -path "*/dist/*" \) -prune -o -type f -print'
| 工具 | 排除語法 | 優勢 |
|---|---|---|
| fd | fd -E node_modules -E .git pattern | 預設忽略 .gitignore、語法簡潔、彩色輸出、平行搜尋快 |
| ripgrep (rg) | rg -g '!node_modules' pattern | 內容搜尋王者、支援 .gitignore、極速 |
| find | -path ... -prune | 系統預裝、功能最全、腳本相容性最好 |
熟練掌握 -path -prune 的短路邏輯與括號分組技巧,能讓 find 在大型專案、系統巡檢、自動化腳本中精準高效地鎖定搜尋範圍,避免無效 I/O 與誤匹配。建議將常用排除模式封裝為 Shell 函數或別名,構建個人化高效工具箱。