在数据管理、科研项目、服务器运维等场景中,经常会遇到这样的问题:
📦 一个数据根目录下面,有成百上千个子目录📊 哪些目录占空间最多?🔍 能不能只统计指定层级、符合条件的目录?
答案是:一条 Shell 脚本就够了。
一、目标需求(通用场景)
我们希望实现以下功能:
指定一个数据根目录
只统计**固定层级(如第 3 层)**的子目录
计算每个目录的磁盘占用大小
支持筛选条件
结果格式化输出并保存到日志文件
整个方案不依赖第三方工具,任何 Linux 服务器都能直接用。
二、核心思路说明
脚本整体分为四步:
使用 find 精确定位到目标层级的目录
遍历每一个目录
使用 du 统计目录大小
通过条件判断筛选结果并写入日志
其中:
find 负责“找”
if 负责“筛”
du 负责“算”
三、基础版:统计固定层级目录大小
这是一个最基础、最通用的模板:
#!/bin/bashBASE="/path/to/data/root"LOG="/path/to/output/dir_size.log"> "$LOG"echo "开始统计指定层级目录的数据量" | tee -a "$LOG"echo "统计时间: $(date)" | tee -a "$LOG"echo "==========================================" | tee -a "$LOG"printf "%-80s %12s\n" "目录路径" "大小(MB)" | tee -a "$LOG"echo "------------------------------------------" | tee -a "$LOG"find "$BASE" -mindepth 3 -maxdepth 3 -type d | while read -r dir; do size_mb=$(du -sm "$dir" 2>/dev/null | awk '{print $1}') rel_path="${dir#$BASE/}" printf "%-80s %12d\n" "$rel_path" "$size_mb" | tee -a "$LOG"doneecho "==========================================" | tee -a "$LOG"echo "完成时间: $(date)" | tee -a "$LOG"
运行后,就能清楚看到每个目录占用了多少空间。
四、进阶一:按目录名筛选
很多时候我们只关心特定类型的目录。
思路
使用 basename 取目录名
使用 grep 判断是否匹配
dirname=$(basename "$dir")if echo "$dirname" | grep -qiE 'keyword1|keyword2'; then ...fi
五、进阶二:按目录大小筛选
如果你只关心大目录,可以加上大小判断。
size_mb=$(du -sm "$dir" 2>/dev/null | awk '{print $1}')if [ "$size_mb" -ge 1024 ]; then ...fi
常见阈值示例:
六、实战推荐:目录名 + 大小双重筛选
这是最常用、最实战的一种写法。
find "$BASE" -mindepth 3 -maxdepth 3 -type d | while read -r dir; do dirname=$(basename "$dir") size_mb=$(du -sm "$dir" 2>/dev/null | awk '{print $1}') if echo "$dirname" | grep -qiE 'keyword' && [ "$size_mb" -ge 500 ]; then rel_path="${dir#$BASE/}" printf "%-80s %12d\n" "$rel_path" "$size_mb" | tee -a "$LOG" fidone
这类脚本非常适合:
七、性能优化:在 find 阶段提前筛选
当目录非常多时,可以把筛选条件前移:
find "$BASE" -mindepth 3 -maxdepth 3 -type d -iname "*keyword*"
| while read -r dir; do
优点:
八、总结
这套方案的核心在于一句话:
用 find 定位范围,用 if 精确筛选,用 du 统计大小
掌握这套思路后,你可以非常灵活地扩展:
统计文件数量
导出 CSV 给 Excel / Python
配合 crontab 做定期数据监控