那個你一直不敢打開的資料夾
你知道是哪個。你的 ~/Downloads。也許是某個共用雲端的備份目錄,也許是某次專案交接丟過來的資料夾。你的電腦裡一定有一個地方,塞了上千個檔案,你從去年就一直說要整理。
你打開它。看到 quarterly-report-final-v3.xlsx 旁邊是 IMG_4821.png,再旁邊是 tax-form-2025.pdf。你關掉它。跟自己說這週末會處理。你不會的。
這篇文章給你一行指令,把整個混亂整理成乾淨的主題式資料夾結構。一個 AI agent 讀取每個檔案、判斷它到底是什麼、建好目錄樹、把所有東西放到對的位置。想像你雇了一個圖書館員,他會先讀完每本書再上架 — 只是這個館員幾分鐘就搞定,不用幾個月。
讀完這篇,你手上會有一個可用的 organize.sh 腳本、一份編碼你整理偏好的 CLAUDE.md 設定檔,以及把兩者套用到任何目錄的能力。
問題:混亂永遠贏
每個開發者至少有一個目錄長這樣:
~/Downloads/
quarterly-report-final-v3.xlsx
IMG_4821.png
meeting-notes-2026-03.md
budget_2026.csv
architecture-diagram.pdf
random-screenshot.jpg
client-contract-signed.pdf
package.json
old-resume-draft.docx
invoice-march.pdf
dataset-users-export.csv
README.md
photo_vacation_042.heic
tax-form-2025.pdf
... (還有 987 個檔案)
沒有結構、沒有命名規則。三年來的下載、專案備份、Slack 匯出、共用雲端同步,全堆在同一個扁平目錄裡。這就是數位版的雜物抽屜 — 只是這個抽屜每週長十個檔案,而且永遠不會被清。
常見的做法是按副檔名分類。所有 PDF 放一個資料夾,所有圖片放另一個。這就像用書的大小來整理圖書館,而不是用主題。一個 PDF 可能是合約、稅單、學術論文或收據。副檔名告訴你容器的形狀,對內容隻字未提。
你真正要的是按意義分類。而這需要讀取每個檔案的內容。
人類做這件事要花一整個工作天。AI agent 幾分鐘就搞定。它打開每個檔案、讀取內容(或描述圖片)、按主題分類。差別就像按信封顏色分信,跟按寄件人分信。
整理後的樣子
Agent 完成後的目標結構:
~/Downloads-organized/
finance/
invoices/
invoice-march.pdf
budgets/
budget_2026.csv
tax/
tax-form-2025.pdf
work/
reports/
quarterly-report-final-v3.xlsx
meeting-notes/
meeting-notes-2026-03.md
contracts/
client-contract-signed.pdf
projects/
code/
package.json
README.md
architecture/
architecture-diagram.pdf
personal/
photos/
IMG_4821.png
photo_vacation_042.heic
random-screenshot.jpg
resumes/
old-resume-draft.docx
data/
exports/
dataset-users-export.csv
每個檔案都在語意上合理的位置。資料夾名稱描述的是檔案的內容,不是檔案的格式。
第一步:設定 CLAUDE.md 整理規則
在 agent 碰任何東西之前,你需要告訴它規則。在工作目錄放一份 CLAUDE.md,它就像 agent 的常駐指令 — 想像成一份跨 session 都有效的 style guide。
在你要跑整理指令的目錄建立這個檔案:
# File Organization Rules
## Directory Structure
Classify files into these top-level categories:
- finance/ — invoices, budgets, tax documents, receipts, financial statements
- work/ — reports, meeting notes, presentations, contracts, proposals
- projects/ — source code, documentation, architecture diagrams, configs
- personal/ — photos, resumes, personal documents, travel records
- data/ — datasets, exports, CSVs, database dumps
- misc/ — anything that does not fit the above categories
## Sub-categorization
Within each top-level category, create subcategories based on document type.
Keep subcategory depth to 2 levels maximum (e.g., finance/invoices/, not finance/invoices/2026/march/).
## Classification Rules
1. Read the file content to determine category. Do NOT rely on filename or extension alone.
2. For images: describe the image content and classify accordingly.
3. For code files: group by project if a package.json or similar manifest is nearby.
4. When uncertain, use misc/ with a descriptive subfolder name.
## Safety
- NEVER delete files. Only move them.
- ALWAYS generate a move log before executing.
- Preserve original filenames unless there are duplicates (append -1, -2, etc.).
## Output
Write a manifest.json listing every move operation as:
{"source": "original/path", "destination": "new/path"}
這份設定可以重複使用。調好一次,未來每次跑都遵守同樣的規則。團隊共用的話,同一份 CLAUDE.md 確保每個人的整理方式一致。
更完整的 CLAUDE.md 撰寫指南,見 CLAUDE.md 完整寫作教學。
第二步:整理腳本
以下是完整的腳本。掃描、分類、dry-run 預覽、執行、產生復原日誌 — 整個 pipeline 在一個檔案裡。
#!/usr/bin/env bash
set -euo pipefail
# === 設定 ===
SOURCE_DIR="${1:?Usage: organize.sh <source-dir> [--dry-run]}"
DRY_RUN=false
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
DEST_DIR="${SOURCE_DIR}-organized"
UNDO_LOG="${DEST_DIR}/.undo-moves.sh"
MANIFEST="${DEST_DIR}/manifest.json"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BATCH_SIZE=50
# === 驗證 ===
if [[ ! -d "$SOURCE_DIR" ]]; then
echo "Error: $SOURCE_DIR is not a directory"
exit 1
fi
FILE_COUNT=$(find "$SOURCE_DIR" -maxdepth 1 -type f | wc -l | tr -d ' ')
echo "Found $FILE_COUNT files in $SOURCE_DIR"
if [[ "$FILE_COUNT" -eq 0 ]]; then
echo "No files to organize."
exit 0
fi
# === 步驟一:產生分類計畫 ===
echo "Generating classification plan..."
claude -p "You are a file organizer. Read the CLAUDE.md in the current directory for rules.
List every file in $SOURCE_DIR (non-recursive, files only).
For each file:
1. Read its contents (first 500 bytes for binary files, full text for small text files).
2. Classify it according to the rules in CLAUDE.md.
3. Determine its destination path under $DEST_DIR.
Output ONLY a valid JSON array to stdout:
[{\"source\": \"path/to/file\", \"destination\": \"path/to/dest\", \"reason\": \"brief classification reason\"}]
No markdown fences. No explanation. Just the JSON array." > "$MANIFEST.tmp"
# === 步驟二:驗證並預覽 ===
if ! python3 -c "import json; json.load(open('$MANIFEST.tmp'))"; then
echo "Error: Agent output is not valid JSON. Check $MANIFEST.tmp"
exit 1
fi
mv "$MANIFEST.tmp" "$MANIFEST"
MOVE_COUNT=$(python3 -c "import json; print(len(json.load(open('$MANIFEST'))))")
echo ""
echo "=== Classification Plan ==="
echo "$MOVE_COUNT files classified."
echo ""
# 預覽前 20 筆
python3 -c "
import json
moves = json.load(open('$MANIFEST'))
for m in moves[:20]:
print(f\" {m['source']} -> {m['destination']}\")
print(f\" reason: {m['reason']}\")
if len(moves) > 20:
print(f' ... and {len(moves) - 20} more')
"
if $DRY_RUN; then
echo ""
echo "[DRY RUN] No files moved. Full plan saved to $MANIFEST"
exit 0
fi
# === 步驟三:執行搬移 ===
echo ""
read -rp "Proceed with moving $MOVE_COUNT files? [y/N] " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && echo "Aborted." && exit 0
echo "#!/usr/bin/env bash" > "$UNDO_LOG"
echo "# Undo log generated $TIMESTAMP" >> "$UNDO_LOG"
echo "# Run this script to reverse all moves" >> "$UNDO_LOG"
echo "" >> "$UNDO_LOG"
python3 -c "
import json, os, shutil
moves = json.load(open('$MANIFEST'))
undo_lines = []
for m in moves:
src = m['source']
dst = m['destination']
dst_dir = os.path.dirname(dst)
os.makedirs(dst_dir, exist_ok=True)
shutil.move(src, dst)
undo_lines.append(f'mv \"{dst}\" \"{src}\"')
print(f' moved: {os.path.basename(src)} -> {dst}')
with open('$UNDO_LOG', 'a') as f:
for line in reversed(undo_lines):
f.write(line + '\n')
print(f'\nDone. {len(moves)} files moved.')
"
chmod +x "$UNDO_LOG"
echo ""
echo "Undo log saved to $UNDO_LOG"
echo "To reverse all moves: bash $UNDO_LOG"
存成 organize.sh,用 chmod +x organize.sh 設為可執行。
第三步:先跑 Dry-Run
一個會搬一千個檔案的腳本,不先看計畫就直接跑?別鬧了。一定要先加 --dry-run:
./organize.sh ~/Downloads --dry-run
輸出會顯示每一筆搬移計畫和 agent 的分類理由:
Found 1037 files in /Users/you/Downloads
=== Classification Plan ===
1037 files classified.
~/Downloads/invoice-march.pdf -> ~/Downloads-organized/finance/invoices/invoice-march.pdf
reason: PDF invoice from March, contains billing line items
~/Downloads/IMG_4821.png -> ~/Downloads-organized/personal/photos/IMG_4821.png
reason: Photograph, EXIF data indicates personal camera
~/Downloads/quarterly-report-final-v3.xlsx -> ~/Downloads-organized/work/reports/quarterly-report-final-v3.xlsx
reason: Excel spreadsheet with quarterly financial data and charts
... and 1034 more
[DRY RUN] No files moved. Full plan saved to ~/Downloads-organized/manifest.json
打開 manifest.json 掃一遍完整清單。找出分類錯的地方。如果 agent 把一張跟工作相關的照片放到 personal/photos/ 而不是 work/,調整 CLAUDE.md 的規則然後重跑。Dry run 只花你幾分鐘的閱讀時間。跳過它會花你一整個下午善後。
第四步:執行並驗證
確認計畫沒問題之後:
./organize.sh ~/Downloads
腳本會要求確認,然後搬移每個檔案並產生復原日誌。如果任何事出了問題 — 哪怕只有一個檔案放錯 — 你有安全網:
bash ~/Downloads-organized/.undo-moves.sh
每一筆搬移都會被反轉,按相反順序執行,完全還原到原始目錄狀態。就像你的檔案系統有了 Ctrl+Z。
處理大型目錄:批次處理
一千個檔案塞進一個 prompt 可能會撞到 agent 的 context window 上限 — 就像試圖一眼讀完一整本小說。解法是分批:每次處理 50 個檔案。
# 把檔案清單切成批次
find "$SOURCE_DIR" -maxdepth 1 -type f > /tmp/filelist.txt
split -l 50 /tmp/filelist.txt /tmp/batch_
# 逐批處理
for batch in /tmp/batch_*; do
FILES=$(cat "$batch" | tr '\n' ',' | sed 's/,$//')
claude -p "Classify these files according to CLAUDE.md rules.
Files: $FILES
Output JSON array: [{\"source\": ..., \"destination\": ..., \"reason\": ...}]" >> "$MANIFEST.partial"
done
# 合併所有批次結果
python3 -c "
import json
results = []
with open('$MANIFEST.partial') as f:
for line in f:
line = line.strip()
if line.startswith('['):
results.extend(json.loads(line))
with open('$MANIFEST', 'w') as f:
json.dump(results, f, indent=2)
print(f'Merged {len(results)} classifications')
"
分批處理也有助於控制 API 速率。如果你用的 API key 有請求限制,在批次之間加入短暫間隔:
for batch in /tmp/batch_*; do
# ... 處理批次 ...
sleep 2 # 尊重 rate limit
done
互動模式:需要手動控制時
上面的腳本是全自動的。但有時候你想自己開車。也許是第一次整理某個目錄,你根本不確定裡面有什麼。
在你要整理的目錄啟動 Claude Code 互動模式:
cd ~/Downloads
claude
先探索,再動手:
> List all files in the current directory grouped by what you think
> their content is. Do not move anything yet. Just show me the groupings.
Agent 讀取檔案,顯示建議的分組。你微調:
> Good, but move all the architecture-*.pdf files to work/architecture
> instead of projects/architecture. And merge "data/exports" into
> "work/data" since these are all work-related exports.
然後執行:
> Now create the directory structure and move all files according to
> the updated plan. Generate an undo script at .undo-moves.sh.
互動模式適合第一次面對某個目錄、你還在摸索裡面到底有什麼的時候。等規則穩定之後,改用腳本模式。把互動模式想成 prototype,腳本是 production 版。
進階:自訂分類規則
預設的分類(finance、work、projects、personal、data)涵蓋大多數情況。但你的工作不是大多數情況。以下是怎麼調整。
合規稽核準備
文件散落五個目錄,合規稽核兩週後到。在 CLAUDE.md 加入這些規則:
## Compliance Categories
- pii/ — any document containing personally identifiable information
(names + addresses, SSNs, email lists, customer databases)
- financial-records/ — invoices, receipts, bank statements, tax filings
- contracts/ — signed agreements, NDAs, service level agreements
- policies/ — internal policy documents, handbooks, SOPs
- evidence/ — audit trails, system logs, access records
- unclassified/ — requires manual review before filing
## Compliance Flags
If a file contains PII, add a "pii_detected": true flag in the manifest.
If a file appears to be a duplicate of another, add "possible_duplicate": "other-file.pdf".
現在 agent 不只整理檔案 — 它還標記敏感內容。unclassified/ 資料夾變成你的待審佇列,不是黑洞。
專案感知整理
清理混合多個 codebase 的專案資料夾:
## Project Detection
Look for project root indicators:
- package.json, Cargo.toml, go.mod, pyproject.toml, Makefile
- Group all files that belong to the same project under projects/{project-name}/
- Detect the project name from the manifest file
- Preserve internal directory structure within each project
這確保相關檔案待在一起。不然一個 README.md 可能跑到 projects/code/,而它所屬的 Cargo.toml 卻被丟到 projects/configs/。Agent 讀取 manifest 檔案,理解專案的邊界。
Workspace 切換:處理不同整理任務
如果你經常從多個來源整理檔案 — 共用雲端、下載資料夾、客戶交接目錄 — 每個來源需要獨立的設定。你的個人下載和合規稽核資料夾不該用同一套分類。就像你不會用同一套歸檔系統來整理廚房和辦公室。
在 Termdock 中,你可以為每個整理任務建立一個 workspace。每個 workspace 記住它的目錄、terminal 配置和 CLAUDE.md 設定。切換 workspace,整個上下文跟著切換。
一個 workspace 做每週下載清理。另一個做季度合規準備。第三個處理客戶交付的檔案。不用重新切目錄,不用找設定檔。Workspace 承載了整個工作脈絡。
想深入了解 terminal workspace 管理,見 終端多工比較:tmux、Termdock 與 Zellij。
效能:實際數據
整理一個 1,200 個檔案的下載目錄的實際數據:
| 指標 | 數值 |
|---|---|
| 總檔案數 | 1,200 |
| 每批數量 | 50 檔 |
| 批次數 | 24 |
| 每批處理時間 | 約 15-30 秒 |
| 總分類時間 | 約 8 分鐘 |
| 搬移執行時間 | 約 5 秒 |
| 總耗時 | 約 9 分鐘 |
瓶頸在分類,不在搬移。Agent 把大部分時間花在讀取檔案內容和決定分類。二進位檔案(圖片、PDF)比較慢,因為 agent 需要解讀它們。文字為主的目錄(code repo、Markdown 筆記、CSV 匯出)分類更快,因為文字內容可以直接解析。
1,200 個檔案,9 分鐘。對比一下你一直拖延的那八個小時。
安全檢查清單
在重要檔案上跑之前,走過這五個防護:
- 先跑 dry-run。 一定要先用
--dry-run執行,檢查 manifest。沒有例外。 - 復原日誌存在。 確認
.undo-moves.sh在任何搬移前就已產生。 - 原始目錄完整保留。 腳本會建立新的
-organized目錄,不會直接修改原始結構。 - 不會刪除任何檔案。 腳本只用
move,不用delete。你的原始檔案存在於目標位置,不是在垃圾桶裡。 - Manifest 就是你的收據。
manifest.json記錄了每一筆搬移和 agent 的分類理由。如果檔案放錯地方,manifest 精確告訴你原因,你可以調整規則。
疑難排解
Agent 輸出不是有效的 JSON。 偶爾 agent 會把 JSON 包在 markdown 區塊裡或加上說明文字。腳本的驗證步驟會抓到這個問題。如果驗證失敗,打開 manifest.json.tmp,移除非 JSON 的內容,手動重跑搬移步驟。
Agent 分類錯誤。 通常表示 CLAUDE.md 的規則有歧義。如果 agent 把發票放到 work/ 而不是 finance/,加一條明確的規則:「包含帳單明細、付款金額或發票編號的文件一律放到 finance/invoices/。」規則模糊,結果就模糊。
Agent 讀不了二進位檔案。 有些 AI CLI 工具對二進位檔案的支援有限。Claude Code 可以直接解讀圖片。對其他二進位格式(.sketch、.fig、專有格式),加一條備援規則:「如果無法讀取檔案內容,根據檔名和副檔名分類。」
搬移時出現權限錯誤。 腳本需要對來源和目標目錄都有寫入權限。用適當的權限執行,或在整理系統目錄時使用 sudo。
你帶走什麼
讀完這篇,你手上有三樣東西:
- 一個腳本(
organize.sh),用 dry-run 安全機制和一鍵復原來分類並搬移檔案。 - 一份設定(
CLAUDE.md),把你的整理偏好編碼成 agent 的持久指令。 - 一個模式,可以套用到任何目錄:改
CLAUDE.md裡的規則,重跑腳本。
第一次跑需要十分鐘設定。之後每次只要一行指令。讀這篇時你腦中浮現的那個混亂下載資料夾?現在就去整理它。動手做比讀再多文章都有價值。
想看 AI CLI agent 在檔案整理之外還能自動化什麼工作,見 AI CLI 工具完整指南。還沒裝好 Claude Code 的話,從第一個小時教學開始。
Ready to streamline your terminal workflow?
Multi-terminal drag-and-drop layout, workspace Git sync, built-in AI integration, AST code analysis — all in one app.