You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将NCDU JSON输出转换为适配D3.js的层级JSON结构

将NCDU JSON转换为D3层级JSON的解决方案

NCDU输出的JSON采用特殊嵌套结构(目录节点后紧跟其子内容数组),要转换成D3兼容的层级格式,需要递归识别目录与文件的结构差异,以下是两种可靠实现方式:

方法一:Python递归处理

Python的递归逻辑能直观处理嵌套结构,同时灵活补充默认字段:

import json
import os

def process_node(node, children_groups=None):
    # 构建基础字段,补充默认值
    processed = {
        "name": node["name"],
        "asize": node.get("asize", 0),
        "dsize": node.get("dsize", 0),
        "ino": node.get("ino", 0),
        "hlnkc": node.get("hlnkc", False),
        "read_error": node.get("read_error", False),
        "nlink": node.get("nlink", 1),
        "notreg": node.get("notreg", False),
        # 提取文件扩展名
        "extension": os.path.splitext(node["name"])[1].lstrip(".") if "." in node["name"] else ""
    }

    if children_groups:
        processed["children"] = []
        for group in children_groups:
            if isinstance(group, list):
                # 数组类型为目录组:[目录节点, 子目录/文件组...]
                dir_node = group[0]
                dir_children = group[1:] if len(group) > 1 else []
                processed["children"].append(process_node(dir_node, dir_children))
            else:
                # 对象类型为单独文件节点
                processed["children"].append(process_node(group))
    return processed

# 读取NCDU原始JSON
with open("data.json", "r") as f:
    ncdu_data = json.load(f)

# 提取根目录节点及子内容组
root_node = ncdu_data[3][0]
root_children = ncdu_data[3][1:]

# 转换并保存结果
flare_format = process_node(root_node, root_children)
with open("flare_output.json", "w") as f:
    json.dump(flare_format, f, indent=2)

关键逻辑说明

  • NCDU结构中,数组代表目录+子内容(第一个元素是目录本身,后续元素是子目录/文件),单独对象是文件
  • 递归遍历所有层级,自动补充dsize、hlnkc等缺失字段的默认值
  • 通过os.path.splitext提取文件扩展名,无扩展名则为空字符串

方法二:jq命令行处理

使用jq的递归函数实现转换,适合无需编写脚本的场景:

  1. 创建转换脚本convert.jq:
# 递归处理单个节点,补充默认字段
def process_node:
  . as $node
  | {
      name: $node.name,
      asize: $node.asize,
      dsize: $node.dsize // 0,
      ino: $node.ino,
      hlnkc: $node.hlnkc // false,
      read_error: $node.read_error // false,
      nlink: $node.nlink // 1,
      notreg: $node.notreg // false,
      extension: ($node.name | split(".") | if length > 1 then last else "" end)
    };

# 处理子内容组,区分目录(数组)和文件(对象)
def process_children:
  .[] | if type == "array" then
          (.[0] | process_node) | .children = (.[1:] | process_children)
        else
          . | process_node
        end;

# 主逻辑:提取根节点并处理所有子内容
.[3] as $root
| ($root[0] | process_node)
| .children = ($root[1:] | process_children)
  1. 执行转换:
jq -f convert.jq data.json > flare_output.json

关键逻辑说明

  • 使用//运算符设置缺失字段的默认值
  • 通过type == "array"判断目录组,递归处理其子内容
  • 用split(".")提取扩展名,无扩展名时返回空字符串

内容的提问来源于stack exchange,提问作者ricardo3889

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:39:56