将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的递归函数实现转换,适合无需编写脚本的场景:
- 创建转换脚本
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)
- 执行转换:
jq -f convert.jq data.json > flare_output.json
关键逻辑说明
- 使用
//运算符设置缺失字段的默认值 - 通过
type == "array"判断目录组,递归处理其子内容 - 用
split(".")提取扩展名,无扩展名时返回空字符串
内容的提问来源于stack exchange,提问作者ricardo3889
相关产品推荐
相关产品推荐

