tree 命令详解与参数实测(Ubuntu 22.04)
tree 命令逐参数实测详解:默认树状图、-L 限深、-d 仅目录、-a 含隐藏、-f 完整路径、-h 大小、-p 权限、--dirsfirst 目录优先、-I 模式排除、--charset ascii 与末行统计,全部回显在 Ubuntu 22.04(tree v2.0.2)实测通过。
tree 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 tree 的每一个参数——默认树状图、
-L限深、-d仅目录、-a含隐藏文件、-f完整路径、-h人类可读大小、-p权限、--dirsfirst目录优先、-I模式排除、--charset ascii字符集与末行统计,全部命令与回显已在 Ubuntu 22.04(tree v2.0.2)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- tree 版本:tree v2.0.2(
tree --version实测) - tree 非默认预装工具,安装方式:
apt install tree(本环境已安装) - 演示目录:
/root/demo/tree/ - 测试数据:
app/src/core/main.go、app/src/utils/str.go、app/src/utils/math.go、app/tests/app_test.go、app/build.log(256K)、README.md、docs/plan.md、隐藏文件.hidden,共 6 个目录 8 个文件
二、命令概览
2.1 语法与测试数据准备
tree 的基本语法是 tree [-选项] [directory ...]:以树状缩进图递归列出目录内容,末尾汇总目录数与文件数。它是 ls 的「结构化升级版」——ls 看一层,tree 一次看穿整个目录树,是讲解项目结构、写文档配图时的高频工具。
💡 技术拓展:"展示目录结构"不止 tree 一条路,常见方式横向对比——
工具 原理/职责 适用场景 tree 树状缩进图递归展示,可控制深度、过滤 文档配图、快速看穿项目结构 ls -R 逐层平铺递归列表,无缩进结构 无 tree 时的降级方案 find 按谓词遍历输出路径,可精确过滤 脚本处理(按类型/名字筛路径) du --max-depth 只展示各级目录的占用汇总 关心"每层多大"而非"有什么" 本文主角是 tree:唯一自带树形缩进与汇总行的方式,展示效果最直观;深度用
-L控制,避免大目录刷屏。
先准备一套带隐藏文件与构建产物的演示数据:
rm -rf /root/demo/tree && mkdir -p /root/demo/tree/app/src/core /root/demo/tree/app/src/utils /root/demo/tree/app/tests /root/demo/tree/docs
printf 'package main\n' > /root/demo/tree/app/src/core/main.go
printf 'package util\n' > /root/demo/tree/app/src/utils/str.go
printf 'package util\n' > /root/demo/tree/app/src/utils/math.go
printf 'test\n' > /root/demo/tree/app/tests/app_test.go
printf '# Demo\n' > /root/demo/tree/README.md
printf 'plan\n' > /root/demo/tree/docs/plan.md
dd if=/dev/zero of=/root/demo/tree/app/build.log bs=1K count=256 status=none
printf 'hide\n' > /root/demo/tree/.hidden
验证数据就绪:
$ ls -lR /root/demo/tree
/root/demo/tree:
total 12
-rw-r--r-- 1 root root 7 Oct 15 06:28 README.md
drwxr-xr-x 4 root root 4096 Oct 15 06:28 app
drwxr-xr-x 2 root root 4096 Oct 15 06:28 docs
/root/demo/tree/app:
total 264
-rw-r--r-- 1 root root 262144 Oct 15 06:28 build.log
drwxr-xr-x 4 root root 4096 Oct 15 06:28 src
drwxr-xr-x 2 root root 4096 Oct 15 06:28 tests
/root/demo/tree/app/src:
total 8
drwxr-xr-x 2 root root 4096 Oct 15 06:28 core
drwxr-xr-x 2 root root 4096 Oct 15 06:28 utils
/root/demo/tree/app/src/core:
total 4
-rw-r--r-- 1 root root 13 Oct 15 06:28 main.go
/root/demo/tree/app/src/utils:
total 8
-rw-r--r-- 1 root root 13 Oct 15 06:28 math.go
-rw-r--r-- 1 root root 13 Oct 15 06:28 str.go
/root/demo/tree/app/tests:
total 4
-rw-r--r-- 1 root root 5 Oct 15 06:28 app_test.go
/root/demo/tree/docs:
total 4
-rw-r--r-- 1 root root 5 Oct 15 06:28 plan.md
2.2 --help 回显
tree --help 帮助较长,以下为实测前 40 行(输出节选,已含本节实测涉及的全部参数;先用 grep 确认了 --charset 参数存在于帮助中):
$ tree --help | grep -n 'charset'
5: [--filelimit #] [--si] [--du] [--prune] [--charset X]
24: --charset X Use charset X for terminal/HTML and indentation line output.
$ tree --help | head -40
usage: tree [-acdfghilnpqrstuvxACDFJQNSUX] [-L level [-R]] [-H baseHREF]
[-T title] [-o filename] [-P pattern] [-I pattern] [--gitignore]
[--matchdirs] [--metafirst] [--ignore-case] [--nolinks] [--inodes]
[--device] [--sort[=]<name>] [--dirsfirst] [--filesfirst]
[--filelimit #] [--si] [--du] [--prune] [--charset X]
[--timefmt[=]format] [--fromfile] [--noreport] [--version] [--help]
[--] [directory ...]
------- Listing options -------
-a All files are listed.
-d List directories only.
-l Follow symbolic links like directories.
-f Print the full path prefix for each file.
-x Stay on current filesystem only.
-L level Descend only level directories deep.
-R Rerun tree when max dir level reached.
-P pattern List only those files that match the pattern given.
-I pattern Do not list files that match the given pattern.
--gitignore Filter by using .gitignore files.
--ignore-case Ignore case when pattern matching.
--matchdirs Include directory names in -P pattern matching.
--metafirst Print meta-data at the beginning of each line.
--info Print information about files found in .info files.
--noreport Turn off file/directory count at end of tree listing.
--charset X Use charset X for terminal/HTML and indentation line output.
--filelimit # Do not descend dirs with more than # files in them.
-o filename Output to file instead of stdout.
------- File options -------
-q Print non-printable characters as '?'.
-N Print non-printable characters as is.
-Q Quote filenames with double quotes.
-p Print the protections for each file.
-u Displays file owner or UID number.
-g Displays file group owner or GID number.
-s Print the size in bytes of each file.
-h Print the size in a more human readable way.
--si Like -h, but use in SI units (powers of 1000).
-D Print the date of last modification or (-c) status change.
--timefmt <f> Print and format time according to the format <f>.
-F Appends '/', '=', '*', '@', '|' or '>' as per ls -F.
--inodes Print inode number of each file.
💡 说明:帮助把参数分为 Listing(列什么:
-a/-d/-L/-P/-I/--noreport等)与 File options(每行附带什么元数据:-p/-s/-h/-u/-g/-D等)两组。--charset X在 usage 与 Listing 组各出现一次,确认存在后才进入 3.10 实测。
2.3 版本确认
$ tree --version
tree v2.0.2 (c) 1996 - 2022 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro
三、参数逐项实测
3.1 默认用法:树状图
不带任何参数,tree 递归画出目录树,连线用 |-- 与 `--,末尾汇总统计:
$ tree /root/demo/tree
/root/demo/tree
|-- README.md
|-- app
| |-- build.log
| |-- src
| | |-- core
| | | `-- main.go
| | `-- utils
| | |-- math.go
| | `-- str.go
| `-- tests
| `-- app_test.go
`-- docs
`-- plan.md
6 directories, 7 files
统计行显示 6 个目录、7 个文件(隐藏文件 .hidden 未计入——默认不列出,见 3.4)。文件排在目录之后、同层内按名称排序。
💡 提示:不带目录参数时 tree 默认列当前目录;末尾统计行可用
--noreport关闭(帮助原文:Turn off file/directory count at end of tree listing),见 Q1。
3.2 -L:限制递归深度
-L level 只向下展开 level 层,适合「先看骨架再看细节」:
$ tree -L 2 /root/demo/tree
/root/demo/tree
|-- README.md
|-- app
| |-- build.log
| |-- src
| `-- tests
`-- docs
`-- plan.md
4 directories, 3 files
与 3.1 对比:深度 2 以内的条目保留,src 之下的 core、utils 不再展开,统计行也随之变为 4 directories, 3 files(只统计已列出的部分)。
💡 提示:浏览大型仓库的标准起手式是
tree -L 2;配合 3.8 的--dirsfirst骨架更清晰。
3.3 -d:仅列出目录
-d(List directories only)过滤掉所有文件,只画目录骨架:
$ tree -d /root/demo/tree
/root/demo/tree
|-- app
| |-- src
| | |-- core
| | `-- utils
| `-- tests
`-- docs
6 directories
$ tree -d -L 2 /root/demo/tree
/root/demo/tree
|-- app
| |-- src
| `-- tests
`-- docs
4 directories
第一段输出统计行从 6 directories, 7 files 变为 6 directories;第二段验证 -d 与 -L 2 可组合,常用于快速了解工程分层。
3.4 -a:显示隐藏文件
-a(All files are listed)把 . 开头的隐藏条目也画进树里:
$ tree -a /root/demo/tree
/root/demo/tree
|-- .hidden
|-- README.md
|-- app
| |-- build.log
| |-- src
| | |-- core
| | | `-- main.go
| | `-- utils
| | |-- math.go
| | `-- str.go
| `-- tests
| `-- app_test.go
`-- docs
`-- plan.md
6 directories, 8 files
与 3.1 对比:顶层多出 .hidden,统计从 7 files 变 8 files。排查配置文件(.env、.gitignore 等)是否就位时必加 -a。
3.5 -f:输出完整路径
-f(Print the full path prefix for each file)给每个条目加上从命令行参数起的完整路径:
$ tree -f /root/demo/tree/docs
/root/demo/tree/docs
`-- /root/demo/tree/docs/plan.md
0 directories, 1 file
plan.md 变成 /root/demo/tree/docs/plan.md。要把 tree 的输出喂给其他命令逐个处理时,-f 让每行自含路径、可直接消费。
3.6 -h:人类可读大小
-h(Print the size in a more human readable way)在每行前加 [大小]:
$ tree -h /root/demo/tree/app
[4.0K] /root/demo/tree/app
|-- [256K] build.log
|-- [4.0K] src
| |-- [4.0K] core
| | `-- [ 13] main.go
| `-- [4.0K] utils
| |-- [ 13] math.go
| `-- [ 13] str.go
`-- [4.0K] tests
`-- [ 5] app_test.go
4 directories, 5 files
build.log 显示 256K(与 dd 写入的 256 块 1K 一致),小文件右对齐显示字节数(13、5),目录显示自身块大小 4.0K。看「哪个文件占了空间」用 -h,需要精确字节用帮助中的 -s。
3.7 -p:显示权限
-p(Print the protections for each file)在每行前加 [权限],格式与 ls -l 一致:
$ tree -p /root/demo/tree/docs
[drwxr-xr-x] /root/demo/tree/docs
`-- [-rw-r--r--] plan.md
0 directories, 1 file
目录 drwxr-xr-x、文件 -rw-r--r--(即 755 与 644)。检查部署产物的权限是否符合预期时,-p 比 ls 逐层翻更直观。
💡 提示:
-p可与-h、-u(属主)、-g(属组)、-D(时间)叠加,组成一条「ls -l 的树状版」。
3.8 --dirsfirst:目录优先排列
--dirsfirst 让同层条目中目录排在前、文件排在后(各自仍按名称排序):
$ tree --dirsfirst /root/demo/tree
/root/demo/tree
|-- app
| |-- src
| | |-- core
| | | `-- main.go
| | `-- utils
| | |-- math.go
| | `-- str.go
| |-- tests
| | `-- app_test.go
| `-- build.log
|-- docs
| `-- plan.md
`-- README.md
6 directories, 7 files
与 3.1 对比:顶层的 app、docs 两个目录提到 README.md 之前,app 层的 src、tests 也排在 build.log 之前。结构感更强,适合放进文档与 README。
3.9 -I:按模式排除
-I pattern(Do not list files that match the given pattern)反向过滤,支持 | 分隔多模式:
$ tree -I 'build.log' /root/demo/tree
/root/demo/tree
|-- README.md
|-- app
| |-- src
| | |-- core
| | | `-- main.go
| | `-- utils
| | |-- math.go
| | `-- str.go
| `-- tests
| `-- app_test.go
`-- docs
`-- plan.md
6 directories, 6 files
$ tree -I '*.log|tests' /root/demo/tree
/root/demo/tree
|-- README.md
|-- app
| `-- src
| |-- core
| | `-- main.go
| `-- utils
| |-- math.go
| `-- str.go
`-- docs
`-- plan.md
5 directories, 5 files
第一个示例排除单个构建产物 build.log(7 files 变 6 files);第二个示例用 *.log|tests 同时排除所有日志与 tests 目录(连目录一起消失,6 directories 变 5 directories)。展示「干净的源码结构」时常用。
3.10 --charset ascii:指定输出字符集
--charset X 指定连线与终端输出使用的字符集。实测前已确认该参数存在(见 2.2 帮助原文),实测效果:
$ tree --charset ascii /root/demo/tree/docs
/root/demo/tree/docs
`-- plan.md
0 directories, 1 file
本环境(tree v2.0.2)的默认连线本就是 |--/`-- 的 ASCII 风格(见 3.1),因此 --charset ascii 输出与默认一致。该参数的价值在于:当终端/locale 处于 UTF-8 且 tree 绘出 Unicode 制表符(│ ├ └)导致乱码时,用它强制回退 ASCII 连线。
3.11 末行统计与目录文件计数
每次 tree 输出的末尾都有一行统计,数量随过滤参数变化(3.1 的 7 files、3.2 的 3 files、3.4 的 8 files、3.9 的 6 files),格式固定为 N directories, M files:
$ tree /root/demo/tree/app/src
/root/demo/tree/app/src
|-- core
| `-- main.go
`-- utils
|-- math.go
`-- str.go
2 directories, 3 files
只含目录不含文件时也会如实显示(见 3.3 的 6 directories)。统计行是「过滤是否生效」的快速校验点——排除前后对比这一行即可确认。
四、实战示例
4.1 项目结构总览
看一个陌生工程的分层,目录优先、只看两层:
$ tree -d -L 2 /root/demo/tree
/root/demo/tree
|-- app
| |-- src
| `-- tests
`-- docs
4 directories
4.2 排除构建产物展示源码结构
写文档/汇报时只保留源码视图,日志与测试目录一并排除:
$ tree -I '*.log|tests' /root/demo/tree
/root/demo/tree
|-- README.md
|-- app
| `-- src
| |-- core
| | `-- main.go
| `-- utils
| |-- math.go
| `-- str.go
`-- docs
`-- plan.md
5 directories, 5 files
4.3 带元数据的产物清单
排查产物大小与权限时,-h 看体积、-p 看权限、-f 输出可直接复制的完整路径:
$ tree -h /root/demo/tree/app
[4.0K] /root/demo/tree/app
|-- [256K] build.log
|-- [4.0K] src
| |-- [4.0K] core
| | `-- [ 13] main.go
| `-- [4.0K] utils
| |-- [ 13] math.go
| `-- [ 13] str.go
`-- [4.0K] tests
`-- [ 5] app_test.go
4 directories, 5 files
$ tree -p /root/demo/tree/docs
[drwxr-xr-x] /root/demo/tree/docs
`-- [-rw-r--r--] plan.md
0 directories, 1 file
$ tree -f /root/demo/tree/docs
/root/demo/tree/docs
`-- /root/demo/tree/docs/plan.md
0 directories, 1 file
五、注意事项与常见问题
Q1:末尾的 6 directories, 7 files 是什么?能去掉吗?
是本次列出的目录/文件计数(统计口径随 -L、-I、-a 等过滤参数变化,见 3.11)。要让输出「纯净」可用于拼接,加 --noreport(帮助原文:Turn off file/directory count at end of tree listing)。
Q2:-I 能同时排除多个模式吗?
能。用 | 分隔,如实测的 -I '*.log|tests' 同时排除了日志文件与 tests 目录(见 3.9)。模式匹配对象是条目名称,目录与文件都会被过滤。
Q3:明明有 .hidden 文件,tree 里为什么看不到?
默认不列 . 开头的隐藏条目,加 -a 即可(见 3.1 与 3.4 的统计行对比:7 files 变 8 files)。这与 ls 的默认行为一致。
Q4:连线字符显示成乱码,怎么换回 ASCII?
加 --charset ascii 强制使用 ASCII 连线(见 3.10,参数存在性已在 2.2 用帮助确认)。本环境默认输出即为 ASCII 风格 |--/`--,无需处理;在 UTF-8 环境下 tree 若绘出 Unicode 制表符(│ ├ └)而终端不支持时,此参数可救急。
Q5:目录太大,tree 输出爆炸怎么办?
两招:-L level 限制深度(见 3.2);--filelimit # 不下钻文件数超过 # 的目录(帮助原文:Do not descend dirs with more than # files in them,如 tree --filelimit 100)。两者可叠加使用。
Q6:想只列出某类文件(比如只看 .go)怎么办?
用 -P pattern(帮助原文:List only those files that match the pattern given),与 -I 互为反操作,如 tree -P '*.go' 只列 Go 源文件;注意匹配不到任何条目的目录默认仍会画出(可配合 --prune 清空空目录,均为帮助原文参数)。
六、参考链接
- tree 官方主页:http://mama.indstate.edu/users/ice/tree/
- Ubuntu 手册页:https://manpages.ubuntu.com/manpages/jammy/en/man1/tree.1.html
- 本机帮助:
tree --help、man tree