macOS 上的目錄樹(directory tree)只是將專案的資料夾階層以縮排文字呈現,而產生目錄樹最可靠的方式,是透過 Terminal 中的 find 取得檔案路徑清單,再將該清單送進一個具決定性的瀏覽器內渲染器,例如 Directory Tree Generator。經典的 tree 指令並未隨 macOS 預設安裝;Apple 已將它從 Command Line Tools 所隨附的 BSD userland 發行版中移除,因此全新的安裝環境會給你一個能用 ls 列出檔案、卻無法自行繪製任何分支線條的 Terminal。這個落差正是為什麼這麼多 Mac 使用者會搜尋 tree 的替代方案:他們想要一段一致的文字區塊,能在貼到 README、issue tracker、Slack 對話串或設計審查時完整保留。下方介紹的工具能將一份嚴格的相對檔案路徑清單,轉成可直接複製的樹狀結構,使用 Unicode 或 ASCII 連接符,逐一驗證每一行,以決定性方式排序,而且絕不上傳輸入內容。Mac 使用者還能受益於正斜線分隔符與 Terminal 輸出相符、可支援 Finder 樂於在資料夾名稱中建立的空格(例如 Application Support),以及保留檔名開頭的小數點(例如 .env 與 .gitignore)。

how to get directory tree in mac
How to Get a Directory Tree in Mac Terminal

為什麼 Mac 使用者尋找 tree 時會碰壁

ls 在 macOS 上隨處可見,但 tree 並非如此。Apple 的 Command Line Tools 僅打包 BSD 工具的一部分,而 tree 從來不在 Apple 所打包的 BSD 版本中,因此原廠的 Mac 安裝完全無法繪製目錄樹。使用者往往在需要將專案結構分享給他人(例如 GitHub issue、code review、pull request 說明或說明文件頁面)時,才會發現自己沒有任何東西可以貼上。

於是三種替代方案反覆出現。部分使用者會安裝 Homebrew 並執行 brew install tree,讓上游的 tree 工具可用;有些人則將 find 的輸出透過管線傳給 sed,手動拼出方框繪製字元;還有一群人會用第三方的 tree 檢視器打開專案。每條路線都有實質的缺點。Homebrew 需要使用者授權、好幾 GB 的相依套件,以及一行 PATH 的修改;一旦協作者在受到管制的 Mac 上無法安裝,說明文件流程就會立刻停擺。手寫的 find -print | sed 單行指令會算錯空格,在三到四層巢狀之後喪失對齊,而且會依 Terminal 寬度產生不同輸出。第三方的 GUI 工具產出的是螢幕截圖而非可選取的文字,而螢幕截圖無法在程式碼搜尋、複製貼上或輔助工具中存活。因此,對 Mac 使用者而言,最乾淨的流程就是保留一個小型的本機步驟來蒐集路徑,再搭配一個能渲染出決定性樹狀結構的網頁工具。macOS Finder 很適合用來以視覺方式瀏覽資料夾階層,但它的欄位檢視與列表檢視都是渲染到螢幕上,而不是渲染成可傳遞的文字,這正是 Apple 在其檔案與資料夾說明頁面中所記載的限制——可複製貼上的結構並非受支援的功能。

從 macOS Terminal 擷取乾淨的路徑清單

下一步是請 Terminal 提供生成器所需同樣的路徑清單:每行一個相對路徑,使用正斜線,每一行都宣告為檔案而非目錄。macOS 上的 find 預設就會產生正斜線輸出,與生成器的分隔符選擇一致,不需要任何重新格式化。Mac 使用者的標準操作步驟如下:

  1. 開啟 Terminal 並 cd 到專案根目錄。在產生任何路徑清單之前,先執行 pwd 確認自己位於正確的資料夾中。
  2. 執行 find . -type f -not -path './.*',列印目前目錄下所有一般檔案,並略過隱藏資料夾。每一行的開頭都會是 ./;貼上之前請先移除這個前置字首,因為生成器會拒絕目前目錄的區段與開頭的分隔符。
  3. 針對你的技術堆疊,以一連串的 -not -path 參數加入排除條件:JavaScript 專案使用 -not -path '*/node_modules/*'、建置產出使用 -not -path '*/dist/*'、Python 虛擬環境使用 -not -path '*/.venv/*',CocoaPods 則使用 -not -path '*/Pods/*'。
  4. 若出現 AppleDouble 中繼資料,可附加 -not -name '._*' 將其移除;該樣式會刪除 Finder 在非 APFS 目的地所產生的 resource-fork 附屬檔。
  5. 使用 pbcopy 將最終輸出複製到剪貼簿。完整指令為 find . -type f -not -path './.*' -not -path '*/node_modules/*' | pbcopy,可直接貼到下一個工具使用。

有兩個 macOS 特有的行為值得留意。APFS(現代 Mac 的預設檔案系統)預設為不區分大小寫,但當磁碟區格式化為區分大小寫的 APFS 時則會區分大小寫,因此同一個專案依其所位於的磁碟區,可能產生不同的檔案清單。開頭的小數點(例如 .env.example 與 archive.v1)在 macOS 上屬於正常的檔名,應完整保留,不要修改。在貼上之前,請勿手動編輯輸出來「整理」它:生成器會以精確字串比對路徑,因此多餘的空格、漏掉的小數點或大小寫不一致,都會造成重複或檔案/目錄衝突,然後以清楚的錯誤訊息指出出問題的那一行。

將路徑清單轉為樹狀結構

路徑清單準備就緒後,請在瀏覽器中開啟 Directory Tree Generator。Mac 使用者的完整流程如下:

  1. 將 find 的完整輸出貼到輸入區,每行一個路徑。請移除每行開頭的 ./;生成器會拒絕目前目錄的區段與開頭的分隔符,因此路徑必須以第一個真正的區段開頭。
  2. 選擇正斜線作為分隔符。macOS 的 find 一律回傳正斜線路徑,若在此選擇反斜線,所有行都會因分隔符違規而被拒絕。
  3. 挑選連接符樣式。Unicode 樣式在 macOS Terminal、支援 UTF-8 的編輯器,以及大多數現代的網頁目的地中都能良好顯示。若樹狀結構會經過無法渲染方框繪製字元的系統(例如某些 Windows 的程式碼審查工具或舊式終端機模擬器),則 ASCII 是較安全的選擇。
  4. 按下 Generate tree。該工具會在記憶體中建置一棵前綴樹,依 UTF-16 code unit 排序子節點,使每個層級的目錄排在檔案之前,驗證下一節列出的所有規則,並從單一小數點根節點開始渲染結果。
  5. 查看節點數並檢視渲染後的樹狀結構是否符合預期。按下 Copy 將樹狀結構送入剪貼簿。若瀏覽器拒絕剪貼簿存取,完整輸出仍會顯示且可供選取以便手動複製。

若有任一行被拒絕,生成器會回報出問題的那一行並清除先前的樹狀結構;不會產生部分或截斷的結果。修正該行後重新生成,再次複製即可。

Unicode 與 ASCII 連接符樣式的比較

生成器的兩種輸出模式結構與排序完全相同;只有連接符字元不同。透過並排閱讀一個小範例,可以清楚看出哪些是樹狀結構本身會攜帶的內容:

樹狀結構元素Unicode 模式ASCII 模式
中段分支接合├──|--
最後一個子節點接合└──`--
垂直延伸│|
根節點標記..

ASCII 欄中的直立線字元不使用特殊字型,因此以 ASCII 模式撰寫的樹狀結構可乾淨地貼到純文字電子郵件、傳統終端機模擬器,以及將在不支援 UTF-8 的環境中檢視的 Markdown 檔案。Unicode 連接符在 macOS Terminal 與大多數現代 IDE 中看起來相當自然,但仍有少數僅限 Windows 的檢視器會將每個方框繪製字元顯示為問號或空方塊。給即將把樹狀結構貼到共享 Slack 頻道、Notion 頁面或 GitHub issue 的 Mac 使用者的建議是:分別以 Unicode 與 ASCII 各生成一次;以 Unicode 版本作為主要複製內容,只有在目的地明顯損壞字元時才退而使用 ASCII。

處理 macOS 路徑清單時會咬人的嚴格規則

生成器會套用一組固定的驗證規則;在 macOS 上處理 find 輸出時,最常出現的規則整理如下。

macOS 上的情況生成器的處理方式
某個路徑使用 /,另一個卻使用 \拒絕整批執行。請在生成前先選定單一分隔符。
資料夾名稱含空格,例如 Application Support完整保留空格;無須加上引號。
開頭的小數點,例如 .env.example 或 .gitignore予以保留,且不會被視為上層遍歷的區段。
同一行與其所宣告的子節點同時出現,例如 src 與 src/index.ts 並存由於宣告為檔案的路徑不能同時作為另一個項目的上層目錄,因此會以檔案/目錄衝突予以拒絕。
同一路徑在清單中出現兩次以重複項目予以拒絕;並標示出第二次出現的位置。
編輯器去掉了最後一行的尾端換行視為空白行並予以拒絕;該次執行會失敗,而不會悄悄漏掉一個檔案。

這些嚴格規則是有意為之。靜默修正會讓相同的輸入在不同工作階段產生兩種不同的樹狀結構,違背決定性渲染器的初衷。輸入上限為整份清單 100,000 個 UTF-16 code unit 以及 2,000 條檔案路徑;每條路徑最多 128 個區段,每個區段最多 255 個 code unit。接著渲染出的樹狀結構會以另一個 500,000 code unit 的上限進行檢查,因為較長的上層前綴會使可見輸出倍增。每個上限皆為包含式:剛好 2,000 行會被接受,第 2,001 行會被拒絕,而且絕不會回傳「前 N 項」、「縮短的檔名」或「抽樣的分支」。

分享前先清理路徑清單

生成器不會讀取本機資料夾,也絕不上傳輸入內容,但你從工具複製出來的任何東西都是純文字,會隨你貼上的地方四處傳遞。一份專案樹往往比程式碼本身透露更多資訊:部署配置、以客戶命名的資料夾、內部代號、基礎架構區域,以及特定檔案的存在(.env.production、infra.tf、secrets.example.json)全都會出現在目錄列表中。請將樹狀結構視為 Finder 的螢幕截圖來看待——對協作很有用,但放在公開的 issue tracker 中則相當危險。

在貼上之前,請先掃描 find 輸出,找出任何不該離開機器的路徑,並從輸入中刪除這些行。該工具不會遮罩密鑰、檢查忽略檔、標記符號連結,也不會比對清單與實際的儲存庫,因此遮罩的工作落在握著鍵盤的人身上。一旦渲染出的樹狀結構看起來正確並已檢查過敏感名稱,便可將其複製到目的地並繼續下一步。