find 是 Linux 最強大、也是最複雜的檔案搜尋工具。本文採「範例優先、原理後補」教學法,從簡單單檔搜尋切入,層層遞進至條件組合、動作執行、效能優化,並提供記憶口訣與避坑指南,助新手快速建立 find 思維模型。

核心語法結構
find [路徑] [選項] [測試條件] [動作]
# 路徑:搜尋起始目錄(預設 .)
# 選項:控制搜尋行為(深度、掛載點、符號連結)
# 測試條件:檔案屬性匹配(名稱、時間、大小、權限、類型、擁有者)
# 動作:對匹配檔案執行操作(列印、執行命令、刪除、歸檔)
階段一:入門三大基本功
1. 按名稱搜尋
find / -name "test" # 精確匹配
find / -name "*.log" # 萬用字元
find / -iname "README*" # 忽略大小寫
find . -name "test" -o -name "demo" # 或邏輯
2. 按時間搜尋
| 參數 | 含義 | 單位 | 範例 |
| -mtime n | 修改時間 n*24h 前 | 天 | -mtime 7 (7天前) |
| -mtime -n | 修改時間 n*24h 內 | 天 | -mtime -1 (24h內) |
| -mtime +n | 修改時間 n*24h 以前 | 天 | -mtime +30 (30天前) |
| -atime | 存取時間 | 天 | 同 -mtime |
| -ctime | 狀態改變時間 | 天 | 同 -mtime |
| -mmin/-amin/-cmin | 分鐘精度 | 分 | -mmin -60 (1小時內) |
3. 按類型與大小搜尋
find . -type f # 一般檔案
find . -type d # 目錄
find . -type l # 符號連結
find . -type b/c/p/s # 區塊/字元裝置/FIFO/Socket
find . -size +100M # 大於 100MB
find . -size -10k # 小於 10KB
find . -size 100c # 正好 100 bytes
# 單位:c=bytes, k=KiB, M=MiB, G=GiB, b=512bytes區塊
階段二:條件組合邏輯(重點掌握)
# 邏輯運算子(優先序:not > and > or)
# 隱性 -a (and) 可省略
# 明性 -o (or) 必須寫出
# 群組 \( ... \) 需轉義括號
# 範例:找 .py 檔且 7 天內修改過且屬於 user1
find /home -name "*.py" -mtime -7 -user user1
# 範例:找 (大於 100M 或 30 天前修改) 且非 .git 目錄
find /data \( -size +100M -o -mtime +30 \) -not -path "*/.git/*"
# 範例:找名稱含 test 或 demo 的一般檔案
find . \( -name "*test*" -o -name "*demo*" \) -type f
口訣:「非非與與或或,括號分組記心中;隱性與省略寫,顯性或必須明。」
階段三:動作執行——從查看到處理
| 動作 | 語法 | 特性 | 範例 |
| -print | 預設 | 輸出路徑,換行分隔 | find . -name "*.tmp" -print |
| -print0 | | Null 字元分隔(配合 xargs -0) | find . -name "*.tmp" -print0 | xargs -0 rm |
| -ls | | 詳細資訊(類似 ls -lids) | find . -name "*.log" -ls |
| -exec | cmd {} \; | 每檔啟動一進程 | find . -name "*.bak" -exec rm {} \; |
| -exec + | cmd {} + | 批次傳遞參數(效率高) | find . -name "*.bak" -exec rm {} + |
| -ok | cmd {} \; | 每檔詢問確認 | find . -name "*.tmp" -ok rm {} \; |
| -delete | 內建刪除 | 效率最高、支援深度優先 | find . -name "*.tmp" -delete |
經典範例:批次壓縮日誌
# 找 7 天前的 .log 檔,打包壓縮
find /var/log -name "*.log" -mtime +7 -exec gzip {} +
# 找空目錄刪除
find /tmp -type d -empty -delete
# 找斷開的符號連結
find / -xtype l -ls
階段四:效能優化選項
| 選項 | 功能 | 適用場景 |
| -maxdepth N | 限制遞迴深度 | 只搜尋前 N 層,避免遍歷深層目錄 |
| -mindepth N | 跳過前 N-1 層 | 從第 N 層開始匹配 |
| -mount / -xdev | 不跨越檔案系統 | 避免掃描 /proc, /sys, 網路掛載、外接磁碟 |
| -follow | 追蹤符號連結 | 搜尋連結目標而非連結本身 |
| -daystart | 時間以當天 00:00 為基準 | 配合 -mtime 更符合直覺 |
階段五:實戰綜合範例(背誦級)
# 1. 專案清理:刪除 __pycache__、.pyc、.pytest_cache
find . \( -name "__pycache__" -o -name "*.pyc" -o -name ".pytest_cache" \) -exec rm -rf {} +
# 2. 找大檔案佔用空間前 20
find /home -type f -size +10M -exec ls -lh {} + | sort -k5 -hr | head -20
# 3. 修正權限:目錄 755、檔案 644
find /var/www -type d -exec chmod 755 {} +
find /var/www -type f -exec chmod 644 {} +
# 4. 備份配置檔(排除 .git、node_modules)
find /etc /home/user -type f \( -name "*.conf" -o -name "*.ini" -o -name "*.yaml" \) \
-not -path "*/.git/*" -not -path "*/node_modules/*" \
-exec tar -rvf config_backup.tar {} +
# 5. 找可疑 SUID 檔案
find / -type f -perm -4000 -ls 2>/dev/null
# 6. 依 inode 刪除難刪檔名
find . -inum 123456 -delete
避坑指南與最佳實務
| 坑點 | 後果 | 正確做法 |
| 根目錄無 -mount 搜尋 | 掃描 /proc /sys /dev 導致卡住、報錯 | 加 -mount 或限定具體路徑 |
| -exec {} \; 大量檔案 | 啟動成萬進程,系統負載飆升 | 改用 -exec {} + 或 -delete / xargs |
| 萬用字元未加引號 | Shell 先展開導致匹配錯誤 | find . -name "*.log" (雙引號) |
| 刪除前未預覽 | 誤刪關鍵檔案 | 先跑 -print/-ls 確認,再加 -delete |
| 忽略隱藏檔 | 遺漏 .gitignore、.env 等關鍵配置 | find 預設包含隱藏檔,無需 -a |
學習路徑建議
- Day 1: 熟練
-name、-type、-size、-mtime 四大核心測試條件
- Day 2: 掌握
-exec +、-delete、-print0 | xargs -0 三種批次處理模式
- Day 3: 練習
() 分組與 -not/-and/-o 邏輯組合
- Day 4: 實戰:專案清理、日誌輪轉、權限修正、備份腳本
- 持續: 閱讀
man find、關注 fd/ripgrep 現代替代工具
find 的學習曲線雖陡峭,但掌握其「路徑→選項→測試→動作」四段式結構與邏輯組合思維,即可將它從「難用指令」轉化為「自動化利器」。建議新手準備一張 A4 速查卡,貼在螢幕邊,每日一範例,兩週成肌肉記憶。