以土豆之名,行学习之实

目录树解析文件系统


概述

目录树解析器是一个Python工具,用于将文本形式的树状目录结构转换为实际的文件系统结构。它能够解析包含Unicode树状字符的文本描述,并自动创建相应的目录和文件。

功能特性

  • 智能解析:自动识别树状结构中的目录和文件

  • 注释支持:忽略行内注释(#符号后的内容)

  • 容错处理:自动创建父目录,支持已存在目录

  • 灵活配置:可指定项目创建的基础目录

  • Unicode支持:完整支持树状结构字符(└, ├, │, ─)

输入格式规范

支持的树状字符

  • ├── :分支节点

  • └── :叶节点

  • :垂直连接线

  • (空格):缩进

目录标记

  • 以斜杠 / 结尾表示目录

  • 示例:src/docs/

文件标记

  • 不以斜杠结尾表示文件

  • 示例:main.pyREADME.md

注释格式

  • 使用 # 符号添加注释

  • 注释内容会被自动忽略

  • 示例:src/  # 源代码目录

输出结构

文件系统创建规则

  1. 根目录检测:自动识别树状结构中的第一个非空行作为项目根目录

  2. 路径构建:所有文件目录都创建在 base_dir/root_dir

  3. 父目录自动创建:必要时自动创建所有父级目录

  4. 存在性检查:使用 exist_ok=True 避免重复创建错误

import os
from pathlib import Path


def parse_tree_structure(tree_text, base_dir="."):
    """
    解析树状结构并创建文件系统

    Args:
        tree_text: 树状结构文本
        base_dir: 基础目录路径,项目将创建在此目录下
    """
    lines = tree_text.strip().split('
')

    # 找到第一个非空行作为根目录
    root_dir = None
    for line in lines:
        if line.strip() and ('└' not in line and '├' not in line and '│' not in line):
            # 提取根目录名(去掉可能的斜杠)
            root_dir = line.strip().rstrip('/')
            break

    if not root_dir:
        print("错误:未找到有效的根目录")
        return

    # 构建完整的路径映射
    path_mapping = {}
    current_indent = -1  # 从-1开始,根目录为0级缩进
    current_path = []

    for line in lines:
        if not line.strip():
            continue

        # 检查是否是根目录行(没有树状符号的行)
        if '└' not in line and '├' not in line and '│' not in line:
            # 这是根目录,已经处理过,跳过
            continue

        # 计算缩进级别
        indent_level = 0
        for char in line:
            if char in [' ', '│', '├', '└', '─']:
                indent_level += 1
            else:
                break

        # 清理行内容,提取文件名
        clean_line = line.strip().replace('├── ', '').replace('└── ', '').replace('│', '').strip()

        if not clean_line:
            continue

        # 处理注释
        if '#' in clean_line:
            clean_line = clean_line.split('#')[0].strip()

        # 根据缩进级别调整当前路径
        while len(current_path) >= indent_level and current_path:
            current_path.pop()

        # 添加到路径映射
        if clean_line:
            if clean_line.endswith('/'):  # 目录
                dir_name = clean_line.rstrip('/')
                current_path.append(dir_name)
                full_path = '/'.join(current_path)
                path_mapping[full_path] = 'directory'
            else:  # 文件
                file_name = clean_line
                current_dir_path = '/'.join(current_path)
                full_path = f"{current_dir_path}/{file_name}" if current_dir_path else file_name
                path_mapping[full_path] = 'file'

    # 创建文件系统
    project_root = os.path.join(base_dir, root_dir)

    # 首先创建项目根目录
    Path(project_root).mkdir(parents=True, exist_ok=True)
    print(f"创建项目根目录: {project_root}")

    for path, item_type in path_mapping.items():
        full_system_path = os.path.join(project_root, path)

        if item_type == 'directory':
            Path(full_system_path).mkdir(parents=True, exist_ok=True)
            print(f"创建目录: {full_system_path}")
        else:
            Path(full_system_path).parent.mkdir(parents=True, exist_ok=True)
            Path(full_system_path).touch()
            print(f"创建文件: {full_system_path}")


# 使用示例
if __name__ == "__main__":
    tree_structure = """
ajax-tutorial/
│
├── index.html          # 主页面
├── style.css           # 样式文件
└── server/             # 模拟服务器文件
    ├── users.json      # 用户数据
    └── api.php         # 模拟 API
"""

    parse_tree_structure(tree_structure, ".")
    print("文件系统创建完成!")