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

如何用jq处理lsblk递归JSON输出以生成指定CSV?

问题:从lsblk递归结构JSON生成磁盘挂载点CSV

我有一份简化后的lsblk工具输出JSON,需要生成CSV文件,展示磁盘名称及其所有挂载点(如果有的话)。目前能处理无嵌套的简单场景,但不知道如何处理包含挂载点的递归children列表。其他相关问题只针对扁平结构的旧版lsblk输出(挂载点非数组)。

期望CSV输出示例

"sda"                       # 无挂载点
"sdb","foo1","foo2","foo3"  # 无顶层挂载点,3个(孙级)子项挂载点

注意事项

  • 所有mountpoints均为数组,可能包含多个元素或为空;
  • mountpoints数组中可能存在null值,但数组始终存在;
  • 仅处理blockdevices列表中type为disk的条目。

输入JSON示例

{
   "blockdevices": [
      {
         "type": "disk",
         "name": "sda",
         "etc" : "ignore",
         "mountpoints": [ null ]
      },{
         "type": "loop",
         "etc" : "ignore everything"
      },{
         "type": "disk",
         "name": "sdb",
         "etc" : "ignore",
         "mountpoints": [ null ],
         "children": [
            {
               "name": "ignore",
               "etc" : "ignore",
               "mountpoints": [ "foo1" ]
            },{
               "name": "ignore",
               "etc" : "ignore",
               "mountpoints": [ null ],
               "children": [
                  {
                     "name": "ignore",
                     "etc" : "ignore",
                     "mountpoints": [ "foo2" ]
                  },{
                     "name": "ignore",
                     "etc" : "ignore",
                     "mountpoints": [ "foo3" ]
                  }
               ]
            }
         ]
      }
   ]
}

解决方案

要处理递归的children结构,核心是深度遍历每个磁盘及其所有子节点,收集所有非null的挂载点,具体实现步骤如下:

1. 递归提取挂载点逻辑

编写递归函数遍历节点及其所有后代:

  • 过滤当前节点mountpoints数组中的null值,收集有效挂载点;
  • 若节点存在children数组,递归处理每个子节点,合并子节点的有效挂载点到当前列表。

2. 示例代码(Python)

import json
import csv

def collect_mountpoints(node):
    mounts = []
    # 处理当前节点挂载点,过滤null
    for mp in node.get('mountpoints', []):
        if mp is not None:
            mounts.append(mp)
    # 递归处理所有子节点
    for child in node.get('children', []):
        mounts.extend(collect_mountpoints(child))
    return mounts

# 加载JSON数据
with open('lsblk_output.json', 'r') as f:
    data = json.load(f)

# 生成CSV行
csv_rows = []
for device in data['blockdevices']:
    if device.get('type') == 'disk':
        disk_name = device['name']
        all_mounts = collect_mountpoints(device)
        # 按示例格式构造CSV行
        row = [f'"{disk_name}"'] + [f'"{mp}"' for mp in all_mounts]
        csv_rows.append(','.join(row))

# 打印输出或保存到文件
for line in csv_rows:
    print(line)
# 保存到文件可替换为:
# with open('disk_mounts.csv', 'w') as f:
#     f.write('\n'.join(csv_rows))

3. 代码说明

  • collect_mountpoints函数:深度遍历节点,递归收集所有有效挂载点;
  • 主逻辑:筛选type为disk的设备,调用递归函数汇总挂载点,生成符合要求的CSV格式行;
  • 输出严格匹配示例,每个字段用双引号包裹,挂载点按遍历顺序排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:47:08