Files
tree-generator/README.md
2026-05-16 14:57:11 +08:00

7.1 KiB
Raw Blame History

tree.sh — 目录树生成脚本

一个用纯 Bash 编写的轻量级目录树生成工具支持忽略配置、递归遍历、文件列表、Markdown 导出和统计信息。无需安装任何依赖,开箱即用。

版本: 1.0.0


功能特性

功能 说明
目录树生成 使用 ├── / └── 字符生成标准树形结构,目录在前、文件在后,按字母排序
文件列表 可选生成完整文件列表(-f),显示所有文件的绝对路径
忽略配置 内置 30+ 种常见忽略模式(.gitnode_modules__pycache__ 等),支持 .treeignore 自定义
深度限制 通过 -d 参数限制递归深度,避免过深遍历
Markdown 导出 默认保存为 tree_output.md,也可自定义输出路径
统计信息 自动统计目录数、文件数和总大小(自动转换为 B / KB / MB / GB
循环检测 基于 inode 检测符号链接循环,防止无限递归
权限处理 对无权限目录显示 [Permission denied],不会中断执行

环境要求

  • 操作系统: Linux 或 macOS
  • Shell Bash 4.0 或更高版本
  • 依赖: 无(仅使用 Bash 内置命令和 statawkbasenamedirnamemkdir 等标准工具)

检查 Bash 版本:

bash --version

安装方法

零安装。 直接下载或克隆脚本后即可运行:

chmod +x tree.sh
./tree.sh -p /path/to/target

也可以将脚本放到 PATH 中的某个目录,方便全局调用:

sudo cp tree.sh /usr/local/bin/tree.sh
tree.sh -p /path/to/target

使用方法

基本用法

# 生成当前目录的树形结构
./tree.sh

# 生成指定目录的树形结构
./tree.sh -p /home/user/project

# 使用相对路径
./tree.sh -p ../some-project

命令行选项

选项 简写 说明 默认值
--path <路径> -p 指定目标目录 当前目录 (.)
--output <文件> -o 指定 Markdown 输出文件 tree_output.md
--depth <N> -d 限制递归深度(正整数) 无限制
--files -f 同时生成文件列表 关闭
--no-stats -s 不显示统计信息 显示
--help -h 显示帮助信息
--version -v 显示版本信息

常用示例

# 生成当前目录的完整树(含文件列表和统计)
./tree.sh -f

# 只查看前 2 层目录结构
./tree.sh -d 2

# 生成项目树并保存到自定义文件
./tree.sh -p /var/www/myapp -o project-tree.md

# 深度 3 + 文件列表 + 保存
./tree.sh -p ./src -d 3 -f -o src-tree.md

# 仅终端输出,不保存 Markdown 文件(重定向)
./tree.sh -p . -s > /dev/null

# 查看帮助
./tree.sh -h

# 查看版本
./tree.sh -v

配置说明

内置忽略列表

脚本默认忽略以下目录和文件类型:

版本控制:

  • .git.svn.hg

包管理 & 缓存:

  • node_modules__pycache__.cache.tox.eggs

构建产物:

  • distbuild.next.nuxt.output.vercel.terraform.vagrant

IDE & 编辑器:

  • .idea.vscode

编译产物:

  • *.pyc*.pyo*.egg-info*.swp*.swo*.swn*.class*.o*.so*.dylib

系统文件:

  • .DS_Store

自定义忽略配置

在目标目录下创建 .treeignore 文件,每行一个忽略模式:

# .treeignore 示例
# 注释以 # 开头

# 忽略特定目录
logs
tmp
*.log

# 忽略特定文件类型
*.bak
*.tmp
*.orig

# 忽略特定名称
.env.local
coverage

规则:

  • 空行和以 # 开头的行会被忽略(作为注释)
  • 支持精确匹配(如 logs)和 glob 通配符(如 *.log
  • 忽略模式会追加到内置列表之后,不会覆盖内置规则

使用示例

示例 1基本目录树

$ ./tree.sh -p ./my-project

终端输出:

my-project/
├── src/
│   ├── main.sh
│   ├── utils/
│   │   ├── helpers.sh
│   │   └── validators.sh
│   └── config.sh
├── tests/
│   ├── test_main.sh
│   └── test_utils.sh
├── README.md
└── tree_output.md

Files:
  /home/user/my-project/src/main.sh
  /home/user/my-project/src/utils/helpers.sh
  /home/user/my-project/src/utils/validators.sh
  /home/user/my-project/src/config.sh
  /home/user/my-project/tests/test_main.sh
  /home/user/my-project/tests/test_utils.sh
  /home/user/my-project/README.md
  /home/user/my-project/tree_output.md

Statistics:
  Directories: 4
  Files:       8
  Total size:  12.34 KB

示例 2限制深度

$ ./tree.sh -p ./my-project -d 2

输出:

my-project/
├── src/
│   ├── main.sh
│   ├── utils/
│   └── config.sh
├── tests/
│   ├── test_main.sh
│   └── test_utils.sh
├── README.md
└── tree_output.md

示例 3生成 Markdown 文件

$ ./tree.sh -p ./my-project -f -o my-tree.md

生成的 my-tree.md 内容:

# Directory Tree

Path: `./my-project`

my-project/ ├── src/ │ ├── main.sh │ ├── utils/ │ │ ├── helpers.sh │ │ └── validators.sh │ └── config.sh ├── tests/ │ ├── test_main.sh │ └── test_utils.sh ├── README.md └── tree_output.md


## Files

  /home/user/my-project/src/main.sh
  ...

## Statistics

- **Directories:** 4
- **Files:** 8
- **Total size:** 12.34 KB

示例 4结合 .treeignore 使用

# 创建 .treeignore
echo -e "*.log\ntmp\ncoverage" > .treeignore

# 运行脚本(自动加载 .treeignore
./tree.sh -p .

注意事项

  1. 路径必须存在且为目录:如果指定的路径不存在或不是目录,脚本会报错退出(退出码 2

  2. 深度参数必须为正整数-d 参数必须传入大于 0 的整数,否则报错退出(退出码 1

  3. 符号链接循环检测:脚本基于 inode 检测循环引用。如果检测到循环,会显示 [cycle detected, skipped] 并跳过,不会无限递归。

  4. 权限问题:遇到无权限读取的目录时,会显示 [Permission denied] 并继续处理其他目录,不会中断整个流程。

  5. 输出文件目录自动创建:如果 -o 指定的输出路径中的目录不存在,脚本会自动创建。

  6. Markdown 文件始终生成:脚本每次运行都会同时输出到终端和保存 Markdown 文件(默认 tree_output.md)。终端输出和 Markdown 内容一致。

  7. 大小写敏感:忽略模式匹配区分大小写。

  8. 隐藏文件:以 . 开头的隐藏文件/目录会被正常遍历(除非被忽略规则匹配)。

  9. 退出码

    • 0:成功
    • 1:参数错误
    • 2:路径无效
    • 3:写入失败

项目信息

  • 项目 ID PROJ-20260509011
  • 功能覆盖: F013F0208 个功能全部测试通过)