本文目录导读:

纯Python实现(跨平台)
#!/usr/bin/env python3
import os
import sys
from pathlib import Path
def tree(directory, prefix="", max_depth=None, current_depth=0):
"""
递归生成树形目录结构
"""
if max_depth is not None and current_depth > max_depth:
return
path = Path(directory)
# 获取目录下的所有项
try:
items = list(path.iterdir())
except PermissionError:
print(f"{prefix}└── [权限拒绝] {directory}")
return
# 排序:目录在前,文件在后
items.sort(key=lambda x: (not x.is_dir(), x.name.lower()))
# 处理最后一项的特殊前缀
for i, item in enumerate(items):
is_last = i == len(items) - 1
# 选择连接线
if is_last:
connector = "└── "
new_prefix = prefix + " "
else:
connector = "├── "
new_prefix = prefix + "│ "
# 打印当前项
if item.is_dir():
print(f"{prefix}{connector}📁 {item.name}/")
tree(item, new_prefix, max_depth, current_depth + 1)
else:
# 显示文件大小
try:
size = item.stat().st_size
size_str = format_size(size)
print(f"{prefix}{connector}📄 {item.name} ({size_str})")
except OSError:
print(f"{prefix}{connector}📄 {item.name}")
def format_size(size):
"""格式化文件大小"""
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024:
return f"{size:.1f} {unit}"
size /= 1024
return f"{size:.1f} TB"
def main():
import argparse
parser = argparse.ArgumentParser(description='显示目录树形结构')
parser.add_argument('path', nargs='?', default='.', help='要显示的目录路径')
parser.add_argument('-d', '--max-depth', type=int, help='最大显示深度')
parser.add_argument('--no-size', action='store_true', help='不显示文件大小')
args = parser.parse_args()
if not os.path.exists(args.path):
print(f"错误:路径 '{args.path}' 不存在")
sys.exit(1)
if not os.path.isdir(args.path):
print(f"错误:'{args.path}' 不是一个目录")
sys.exit(1)
print(f"📁 {os.path.abspath(args.path)}/")
tree(args.path, max_depth=args.max_depth)
if __name__ == "__main__":
main()
Bash脚本实现(Linux/Unix)
#!/bin/bash
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
show_tree() {
local dir="$1"
local prefix="$2"
local max_depth="$3"
local current_depth="$4"
# 深度检查
if [[ -n "$max_depth" && "$current_depth" -gt "$max_depth" ]]; then
return
fi
# 获取项目列表
local items=("$dir"/*)
local total=${#items[@]}
local count=0
for item in "${items[@]}"; do
# 跳过没有权限的文件
[[ ! -r "$item" ]] && continue
count=$((count + 1))
local is_last=false
[[ $count -eq $total ]] && is_last=true
# 选择连接线
if $is_last; then
local connector="└── "
local new_prefix="${prefix} "
else
local connector="├── "
local new_prefix="${prefix}│ "
fi
# 获取文件名
local name=$(basename "$item")
if [[ -d "$item" ]]; then
echo -e "${prefix}${connector}${BLUE}📁 ${name}/${NC}"
show_tree "$item" "$new_prefix" "$max_depth" $((current_depth + 1))
else
# 获取文件大小
local size=$(du -h "$item" 2>/dev/null | cut -f1)
echo -e "${prefix}${connector}${GREEN}📄 ${name}${NC} ${YELLOW}(${size})${NC}"
fi
done
}
# 主函数
main() {
local path="${1:-.}"
local max_depth="${2:-}"
# 检查路径是否存在
if [[ ! -e "$path" ]]; then
echo "错误:路径 '$path' 不存在"
exit 1
fi
# 获取绝对路径
local abs_path=$(cd "$path" && pwd)
echo -e "${BLUE}📁 ${abs_path}/${NC}"
show_tree "$path" "" "$max_depth" 0
}
# 使用示例
if [[ $# -eq 0 ]]; then
echo "用法: $0 <目录路径> [最大深度]"
echo "示例: $0 /home/user/project 3"
exit 0
fi
main "$@"
Node.js实现
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
class TreeGenerator {
constructor(rootPath, options = {}) {
this.rootPath = rootPath;
this.maxDepth = options.maxDepth || Infinity;
this.showHidden = options.showHidden || false;
this.showSize = options.showSize !== false;
}
generate() {
const absPath = path.resolve(this.rootPath);
console.log(`📁 ${absPath}/`);
this._traverse(absPath, '');
}
_traverse(dirPath, prefix, depth = 0) {
if (depth > this.maxDepth) return;
try {
const items = fs.readdirSync(dirPath, { withFileTypes: true });
// 过滤隐藏文件
const filtered = this.showHidden ?
items : items.filter(item => !item.name.startsWith('.'));
// 排序:目录在前
filtered.sort((a, b) => {
if (a.isDirectory() !== b.isDirectory()) {
return a.isDirectory() ? -1 : 1;
}
return a.name.localeCompare(b.name);
});
filtered.forEach((item, index) => {
const isLast = index === filtered.length - 1;
const connector = isLast ? '└── ' : '├── ';
const newPrefix = isLast ? `${prefix} ` : `${prefix}│ `;
const itemPath = path.join(dirPath, item.name);
if (item.isDirectory()) {
console.log(`${prefix}${connector}📁 ${item.name}/`);
this._traverse(itemPath, newPrefix, depth + 1);
} else {
if (this.showSize) {
const stats = fs.statSync(itemPath);
const size = this._formatSize(stats.size);
console.log(`${prefix}${connector}📄 ${item.name} (${size})`);
} else {
console.log(`${prefix}${connector}📄 ${item.name}`);
}
}
});
} catch (err) {
console.error(`${prefix}└── [错误] ${err.message}`);
}
}
_formatSize(bytes) {
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(1)} ${units[unitIndex]}`;
}
}
// 命令行接口
if (require.main === module) {
const args = process.argv.slice(2);
const options = {};
let targetPath = '.';
args.forEach((arg, index) => {
if (arg === '-d' || arg === '--depth') {
options.maxDepth = parseInt(args[index + 1]);
} else if (arg === '-a' || arg === '--all') {
options.showHidden = true;
} else if (arg === '--no-size') {
options.showSize = false;
} else if (!arg.startsWith('-')) {
targetPath = arg;
}
});
const tree = new TreeGenerator(targetPath, options);
tree.generate();
}
简单实用的Python版本
#!/usr/bin/env python3
import os
def simple_tree(startpath, indent=0):
"""简单版本的树形目录显示"""
for item in os.listdir(startpath):
# 跳过隐藏文件
if item.startswith('.'):
continue
item_path = os.path.join(startpath, item)
prefix = '│ ' * indent + '├── '
if os.path.isdir(item_path):
print(f"{prefix}📁 {item}/")
# 递归进入子目录
simple_tree(item_path, indent + 1)
else:
# 获取文件大小
size = os.path.getsize(item_path)
if size < 1024:
size_str = f"{size}B"
elif size < 1024*1024:
size_str = f"{size/1024:.1f}KB"
else:
size_str = f"{size/(1024*1024):.1f}MB"
print(f"{prefix}📄 {item} ({size_str})")
if __name__ == "__main__":
import sys
path = sys.argv[1] if len(sys.argv) > 1 else "."
print(f"📁 {os.path.abspath(path)}/")
simple_tree(path)
使用示例
保存脚本后,给予执行权限:
chmod +x tree.py
运行脚本:
# 显示当前目录 ./tree.py # 显示指定目录,深度为3 ./tree.py /path/to/project -d 3 # Bash脚本使用 ./tree.sh /path/to/project 3 # Node.js版本 ./tree.js /path/to/project --depth 3 --all
这些脚本都支持:
- 递归显示目录结构
- 使用Unicode字符画树形图
- 显示目录和文件图标
- 显示文件大小
- 控制显示深度
- 友好的错误处理
选择适合你需求的版本即可!