#!/bin/bash # 磁盘占用分析工具 - 生成交互式HTML报告 # 使用方法: ./disk_analyzer.sh [目录路径] [输出文件名] [最大深度] # 默认参数 TARGET_DIR="${1:-$PWD}" OUTPUT_FILE="${2:-disk_usage_report.html}" MAX_DEPTH="${3:-3}" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}=== 磁盘占用分析工具 ===${NC}" echo -e "目标目录: ${GREEN}$TARGET_DIR${NC}" echo -e "输出文件: ${GREEN}$OUTPUT_FILE${NC}" echo -e "最大深度: ${GREEN}$MAX_DEPTH${NC}" echo "" # 检查目录是否存在 if [ ! -d "$TARGET_DIR" ]; then echo -e "${RED}错误: 目录 $TARGET_DIR 不存在${NC}" exit 1 fi # 检查du命令是否可用 if ! command -v du >/dev/null 2>&1; then echo -e "${RED}错误: 未找到du命令${NC}" exit 1 fi echo -e "${YELLOW}正在收集磁盘使用数据...${NC}" # 创建HTML文件头部 cat > "$OUTPUT_FILE" << 'EOF' 磁盘使用情况分析

🗂️ 磁盘使用情况分析

交互式目录树 - 点击查看详细信息

-
总大小
-
项目数量
-
平均大小
EOF # 收集磁盘使用数据并直接写入HTML echo -e "${BLUE}正在扫描目录结构...${NC}" # 格式化大小的函数 format_size() { local bytes=$1 if [ $bytes -ge 1073741824 ]; then echo "$(awk "BEGIN {printf \"%.2f\", $bytes/1073741824}")GB" elif [ $bytes -ge 1048576 ]; then echo "$(awk "BEGIN {printf \"%.2f\", $bytes/1048576}")MB" elif [ $bytes -ge 1024 ]; then echo "$(awk "BEGIN {printf \"%.2f\", $bytes/1024}")KB" else echo "${bytes}B" fi } # 获取磁盘使用数据 TEMP_DATA=$(mktemp) du -k --max-depth="$MAX_DEPTH" "$TARGET_DIR" 2>/dev/null | sort -nr | head -50 > "$TEMP_DATA" # 检查是否有数据 if [ ! -s "$TEMP_DATA" ]; then echo -e "${RED}警告: 无法获取磁盘使用数据${NC}" echo -e "${YELLOW}可能的原因: 权限不足、目录不存在或du命令不可用${NC}" # 写入无数据提示 cat >> "$OUTPUT_FILE" << 'EOF'

❌ 无法获取数据

可能的原因:

  • 权限不足,请尝试使用 sudo
  • 目录不存在或无法访问
  • du 命令不可用
EOF else echo -e "${GREEN}找到 $(wc -l < "$TEMP_DATA") 个目录项${NC}" # 读取最大大小用于计算百分比 MAX_SIZE_KB=$(head -1 "$TEMP_DATA" | awk '{print $1}') MAX_SIZE_BYTES=$((MAX_SIZE_KB * 1024)) # 计算统计信息 TOTAL_ITEMS=$(wc -l < "$TEMP_DATA") TOTAL_SIZE_FORMATTED=$(format_size $MAX_SIZE_BYTES) AVG_SIZE_BYTES=$((MAX_SIZE_BYTES / TOTAL_ITEMS)) AVG_SIZE_FORMATTED=$(format_size $AVG_SIZE_BYTES) # 处理每一行数据并写入HTML while IFS=$'\t' read -r size_kb path; do if [ -n "$size_kb" ] && [ -n "$path" ]; then size_bytes=$((size_kb * 1024)) human_size=$(format_size $size_bytes) percentage=$(awk "BEGIN {printf \"%.1f\", ($size_bytes/$MAX_SIZE_BYTES)*100}") # 转义路径中的特殊字符 escaped_path=$(echo "$path" | sed 's/&/\&/g; s//\>/g; s/"/\"/g; s/'"'"'/\'/g') # 计算目录层级(用于缩进) level=$(echo "$path" | tr -cd '/' | wc -c) indent=$((level * 20)) # 写入HTML树项 cat >> "$OUTPUT_FILE" << EOF
📁
$escaped_path
$human_size
EOF fi done < "$TEMP_DATA" fi # 清理临时文件 rm -f "$TEMP_DATA" # 写入HTML文件尾部 cat >> "$OUTPUT_FILE" << EOF
EOF echo "" echo -e "${GREEN}✅ 分析完成!${NC}" echo -e "HTML报告已生成: ${GREEN}$OUTPUT_FILE${NC}" echo "" echo -e "${BLUE}📊 使用说明:${NC}" echo -e " • 在浏览器中打开: ${YELLOW}$OUTPUT_FILE${NC}" echo -e " • 点击目录名展开/收起" echo -e " • 使用搜索框过滤结果" echo -e " • 按大小排序查看最大的目录" echo -e " • 快捷键: Ctrl+F(搜索), Ctrl+E(展开), Ctrl+R(收起)" echo "" echo -e "${YELLOW}💡 提示:${NC}" echo -e " • 如需更深层扫描,请增加深度参数" echo -e " • 如遇权限问题,请使用 sudo 运行" echo -e " • 大目录扫描可能需要较长时间" echo "" # 显示文件大小 if [ -f "$OUTPUT_FILE" ]; then FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1) echo -e "生成的HTML文件大小: ${GREEN}$FILE_SIZE${NC}" fi # 尝试自动打开浏览器(可选) if command -v xdg-open >/dev/null 2>&1; then echo -e "${BLUE}是否要在浏览器中打开报告? (y/N)${NC}" read -t 10 -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo -e "${YELLOW}正在打开浏览器...${NC}" xdg-open "$OUTPUT_FILE" & fi elif command -v open >/dev/null 2>&1; then echo -e "${BLUE}是否要在浏览器中打开报告? (y/N)${NC}" read -t 10 -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo -e "${YELLOW}正在打开浏览器...${NC}" open "$OUTPUT_FILE" & fi fi