CMD 中的 tree 指令會在螢幕上繪製目錄結構,但輸出會隨著捲動而滑過,複製貼上到聊天視窗時可能會遺失其方框繪製字符,而且也無法保證對同一個資料夾執行兩次,在複製出來後會長得一模一樣。若要在 CMD 中取得一份能以穩定文字形式存活下來、放入 README、議題或程式碼審查中的目錄樹,可靠的工作流程是從殼層傾印一份嚴格的相對路徑清單,將該清單送入 Directory Tree Generator,然後挑選與輸出貼上位置相符的連接線樣式。這個工具會把每行一條的相對路徑轉成一個單一顯示根節點加上已排序的分支,而且同樣的輸入內容永遠會產生同樣的渲染輸出,因為排序依據是 UTF-16 字碼單元,而非地區設定、修改日期或輸入順序。解析、驗證、排序、渲染和剪貼簿複製都在目前的分頁中執行,因此檔名與資料夾結構絕不會離開產生清單的這台機器。

為何內建的 tree 指令在產生可分享輸出時力有未逮
CMD 原生的 tree 指令是為單一消費者設計的:你正坐在它前面的終端機。預設模式使用的 Unicode 字符,部分 Windows 主控台會處理錯誤,即使能正確渲染,結果仍是螢幕輸出,而非一份穩定的文件。改用 tree /A 會把這些字符換成 +, - 與 \ 字元,大多數複製貼上的路徑都能撐過,但底層的限制仍然存在。
- 排序遵循底層檔案系統,而 NTFS、ReFS、exFAT 與網路共用之間各不相同。對同一個資料夾執行同一道指令兩次,可能會產生肉眼可見的不同順序。
- 當某一層級的子節點順序改變時,縮排也會跟著在兩次執行間位移,這讓產生出的樹狀圖差異比對變得雜訊過多。
- 不支援合併多個根節點的樹狀圖。tree 一次只能走訪一個根路徑。
- 字符並非總是能在往返經過聊天軟體、電子郵件或網頁表單後還完整存活。即使是 ASCII 的分支字元,有時也會掉進會剝除或替換它們的渲染器中。
- 在發佈前沒有辦法從樹狀圖中遮蔽部分內容,除非手動編輯一份已經排版好的區塊。
對於一份會放進 README、議題範本或拉取請求說明中的樹狀圖,你真正想要的是一份穩定的文字,每次從同一份來源清單重新產生時,其欄位排版都會一致。這個目標位於 tree 上游一步,也就是一份嚴格的相對檔案路徑清單。
何時路徑清單勝過在本機執行 tree
即使 CMD 已經打開並準備就緒,仍然存在執行 tree 是錯誤起點的真實情境。
- 你在目標機器上沒有殼層存取權,但你手上有清單、匯出檔,或同事貼過來的內容。你能取得的輸入只有一串路徑。
- 你想為客戶面向的文件遮蔽樹狀圖的部分內容。從路徑清單中抹除名稱,比在已渲染的樹狀圖上逐一清洗來得更快且更不容易出錯。
- 你想要記錄的資料夾存在於不同的作業系統、建置產出物,或未掛載為磁碟機的備份中。
- 你需要確定性的輸出。今天從一份乾淨的路徑清單產生的樹狀圖,明天渲染出來仍會位元組級一致,不受底層檔案系統如何決定目錄項目順序影響。
- 樹狀圖太深,終端機無法以乾淨的縮排顯示。產生器會從單一小數點根節點渲染前置字串,並維持在其輸出上限之內,因此深層樹狀圖仍可解析,而不會在某個字符中間斷行。
在上述每一種情況下,務實的做法是跳過 CMD 的 tree,直接從路徑清單開始。
從 CMD 傾印一份乾淨的相對路徑清單
- 開啟 CMD 並切換到專案根目錄,例如 cd "C:\Users\you\projects\demo"。
- 若只要列出檔案,請執行 dir /S /B /A-D。/S 旗標會遞迴,/B 會去除頁首並使用裸路徑,/A-D 會排除目錄項目,使每一行都是一個檔案。
- 若要同時列出檔案與資料夾,請執行 dir /S /B。在裸格式下,資料夾那一行結尾不會帶斜線;檔案那一行結尾則是檔名。
- 在標題列上按右鍵,選擇「標記」,拖曳以選取該區塊,按 Enter 將它複製到剪貼簿。
- 把該區塊貼到純文字編輯器中。把每一行開頭的絕對路徑前綴移除,使每一行都是相對於專案根目錄的路徑,例如把 C:\Users\you\projects\demo\ 取代為空字串。
- 確認分隔符號樣式在每一行之間都一致。如果有任何一行使用正斜線而其他行使用反斜線,請在貼到工具之前先把清單標準化。
- 儲存清理過的清單。它現在看起來應該像一欄路徑,例如 src\index.ts、src\components\Button.tsx 與 README.md,以換行字元分隔且不含空行。
這份清單就是產生器所預期的輸入。在此階段就移除空行、重複分隔符號、點段,以及任何絕對路徑前綴,可以避免產生過程中最常見的拒絕訊息。
使用 Directory Tree Generator 建立可分享的樹狀圖
- 在你打算複製結果的同一個瀏覽器分頁中開啟 Directory Tree Generator。解析、排序、渲染與剪貼簿寫入期間,任何東西都不會離開這個分頁。
- 把清理過的路徑清單貼到輸入區,每行一條路徑,每行使用相同的分隔符號樣式。把分隔符號切換鈕設為反斜線以對應 Windows 風格路徑,或設為正斜線以對應 POSIX 風格路徑。
- 挑選連接線樣式。對 GitHub、Notion 與現代 Markdown 檢視器使用 Unicode (├──、└──、│)。對終端機、嚴格過濾器後方的程式碼區塊,或會剝除非 ASCII 字元的 wiki 使用 ASCII (|--、`--、|)。
- 點擊「Generate tree」。工具會以換行字元切分,移除每行 CRLF 結尾的單一 carriage return,並拒絕空行、重複路徑、與切換鈕不符的分隔符號、點段、父段、絕對路徑,以及任何跨越段落或字碼單元邊界的行。
- 查看節點數與渲染出的樹狀圖。輸出永遠以單一小數點作為顯示根節點的開頭;在每一層級中,目錄會出現在檔案之前;兄弟節點依 UTF-16 字碼單元排序。
- 點擊「Copy」。整份樹狀圖會以非同步方式寫入剪貼簿。如果瀏覽器拒絕剪貼簿權限,渲染出的樹狀圖仍可選取,讓你用 Ctrl+C 或 Cmd+C 手動複製。
- 把結果貼到 README、議題範本、架構說明或程式碼審查中。無論目的端格式器如何排版程式碼區塊,連接線樣式與排序都會與工具所產生的一致。
如果某一行被拒絕,工具會回報該違規的行號,而不會丟掉其餘輸入。修正該行後再點一次 Generate;絕不會產生局部樹狀圖。
產生器強制執行的輸入規則
限制是明確的、驗證是嚴格的,被拒絕的輸入絕不會被悄悄截斷。了解確切規則能避免最常見的意外。
| 限制 | 允許值 | 在邊界上的行為 |
|---|---|---|
| 輸入總大小 | 100,000 個 UTF-16 字碼單元 | 在上限時接受;再多一個字碼單元就拒絕執行 |
| 路徑行數 | 2,000 條路徑 | 第 2,001 行會連同其行號被拒絕 |
| 每條路徑的段落數 | 128 個段落 | 第 129 個段落會拒絕該條路徑 |
| 段落長度 | 255 個 UTF-16 字碼單元 | 再多一個字碼單元就拒絕該段落 |
| 渲染輸出 | 500,000 個 UTF-16 字碼單元 | 渲染中止而非截斷 |
除了數值上限之外,工具還會拒絕包含下列情況的清單:空行(包括最後一筆項目結尾的尾端空行)、在同一個切換鈕下混用分隔符號的路徑、絕對路徑、開頭分隔符號、Windows 磁碟機根目錄形式、由重複或尾端分隔符號造成的空段落、. 或 .. 段落、名稱中含有 ASCII 控制字元、完全重複的路徑、檔案/目錄衝突,以及任一方向的前綴衝突。帶有一般空格與點的名稱(例如 .env.example、data file.json、archive.v1 與 README draft.md)會原樣保留,字母大小寫也會保留,這就是為什麼 Docs/readme.md 與 docs/readme.md 會被視為兩筆不同的項目。
Unicode 與 ASCII 分支字元的比較
兩種連接線樣式都適用於記錄目錄結構;選擇的重點在於輸出將在哪裡被渲染,而非樹狀圖本身代表什麼。
- Unicode 模式使用方框繪製字元:├── 表示中間兄弟節點,└── 表示群組中的最後一個兄弟節點,│ 表示父節點下方的垂直縮排。輸出結果在 GitHub、GitLab、Bitbucket、Notion、Slack 程式碼區塊以及大多數現代 Markdown 檢視器中都能自然閱讀。
- ASCII 模式使用一般鍵盤字元:|--、`-- 與 |。輸出結果在缺少方框繪製支援的地區設定或字型的終端機中、在經過嚴格 UTF-8 剝除的貼上程式碼區塊中,以及在純文字電子郵件或 wiki 渲染中,都能可靠閱讀。
在兩者之間切換需要重新點擊 Generate tree。一旦連接線切換鈕變動,工具會立即清除先前的輸出,因此舊的樹狀圖不會被誤認為是當前設定的結果。
Privacy, sorting, and what the result actually represents
The generator is a deterministic text transformer, not a filesystem scanner. Knowing that shapes realistic expectations about what the output can and cannot say about the source project.
- Processing location. Parsing, validation, sorting, rendering, and clipboard writing all happen in the current browser tab. File names and folder structure are not uploaded to Lizely or sent to an external API.
- Sorting. Within each level, directories come first, and within the directory group and the file group, names are compared by UTF-16 code units. The ordering is deterministic across supported browsers and independent of locale, operating-system collation, input order, modification time, and filesystem metadata.
- Root convention. The output always begins with a single line containing a dot, the displayed root. Every child of that root is one segment deep, regardless of how the source paths were nested.
- Case sensitivity. Comparisons are exact JavaScript string compares, so Docs/readme.md and docs/readme.md remain distinct. If the same tree is later rendered on a case-insensitive filesystem such as NTFS, macOS HFS+, or APFS, the displayed ordering still matches what the generator produced.
- What the tool does not do. It does not read your disk, read folder metadata, verify that a path exists, label symlinks, calculate sizes, redact secrets, inspect ignore files, or compare the typed list with a real repository. Review the result before publishing; project trees can leak module names, customer names, or deployment layouts even when file contents are absent.
For a CMD-driven workflow, the final loop is straightforward: dump a clean relative path list, paste into Directory Tree Generator, pick a separator and connector style, generate, review the node count, and copy. That path covers the trip from the console output of tree to a stable, paste-ready directory tree in your documentation.