首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用jq将嵌套的JSON文件制表

如何使用jq将嵌套的JSON文件制表
EN

Stack Overflow用户
提问于 2019-06-06 05:58:45
回答 1查看 306关注 0票数 0

我有以下JSON文件,我想用jq工具解析它,有人建议我使用它,但我还是个新手。有3个父节点具有相同的子节点名称。父节点是MNR、GNR和MSNR,每个节点都有名为N1、N2、NR_i和NR_f的子节点。

代码语言:javascript
运行
复制
{
  "Main": {
    "Document": "Doc.1",
    "Cini": "DDFR",
    "List": {
      "SubList": {
        "CdTa": "ABC",
        "NN": "XYZ",
        "ND": {
          "RiS": {
            "RiN": {
              "NSE14": {
                "MNRs": {
                  "MRD": [
                    {
                      "NR": {
                        "N1": "393",
                        "N2": "720",
                        "SNR": {
                          "NR_i": "203",
                          "NR_f": "49994"
                        }
                      }
                    },
                    {
                      "NR": {
                        "N1": "687",
                        "N2": "345",
                        "SNR": {
                          "NR_i": "55005",
                          "NR_f": "1229996"
                        }
                      }
                    }
                  ]
                },
                "GNRs": {
                  "RD": {
                    "NR": {
                      "N1": "649",
                      "N2": "111",
                      "SNR": {
                        "NR_i": "55400",
                        "NR_f": "877"
                      }
                    }
                  }
                },
                "MSNRs": {
                  "NR": [
                    {
                      "N1": "748",
                      "N2": "5624",
                      "SNR": {
                        "NR_i": "8746",
                        "NR_f": "7773"
                      }
                    },
                    {
                      "N1": "124",
                      "N2": "54",
                      "SNR": {
                        "NR_i": "8847",
                        "NR_f": "5526"
                      }
                    }
                  ]
                }
              },
              "NSE12": {
                "MBB": "990",
                "MRB": "123"
              },
              "MGE13": {
                "TBB": "849",
                "TRB": "113"
              }
            }
          }
        }
      }
    }
  }
}

使用这段代码,我得到了以下代码

代码语言:javascript
运行
复制
.Main.List.SubList.ND.RiS.RiN.NSE14.MNRs.MRD

[
  {
    "NR": {
      "N1": "393",
      "N2": "720",
      "SNR": {
        "NR_i": "203",
        "NR_f": "49994"
      }
    }
  },
  {
    "NR": {
      "N1": "687",
      "N2": "345",
      "SNR": {
        "NR_i": "55005",
        "NR_f": "1229996"
      }
    }
  }
]

使用这些命令,我得到了每个子对象的a列单独的值,其他的都是null。

代码语言:javascript
运行
复制
.. | .N1?
.. | .N2?
.. | .NR_i?
.. | .NR_f?

我的输出远远不是我想要的,因为我想提取每个父母的孩子,并在下面的表格中列出。

代码语言:javascript
运行
复制
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
|             MNRs              |          GNRs            |           MSNRs          |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| N1   | N2   | NR_i  | NR_f    | N1  | N2  | NR_i  | NR_f | N1  | N2   | NR_i | NR_f |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| 393  | 720  | 203   | 49994   | 649 | 111 | 55400 | 877  | 748 | 5624 | 8746 | 7773 |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| 687  | 345  | 55005 | 1229996 |     |     |       |      | 124 | 54   | 8847 | 5526 |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+ 

也许有人能帮我这个忙。提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-06 11:48:55

由于输入JSON的性质仅通过示例给出,因此让我们首先定义一个用于线性化.NR的过滤器

代码语言:javascript
运行
复制
# Produce a stream of arrays
def linearize:
  if type == "array" then .[] | linearize
  else [ .N1, .N2, .SNR.NR_i, .SNR.NR_f]
  end;

现在可以在保留顶级组的同时提取相关数据,如下所示:

代码语言:javascript
运行
复制
.Main.List.SubList.ND.RiS.RiN.NSE14
| [to_entries[]
| [.key]
  + [.value | .. | objects | select(has("NR")) | .NR | [ linearize ]] ]

因为输入JSON不是统一的,所以通过使用以下映射增强上面的管道将有助于确保一致性:

代码语言:javascript
运行
复制
| map(if length > 2 then [.[0], [.[1:][][]]] else . end)

这会产生一个JSON数组,结构如下:

代码语言:javascript
运行
复制
[["MNRs",[["393","720","203","49994"]],[["687","345","55005","1229996"]]],
 ["GNRs", ...

为了从这个中间结果中获得表的第一个数据行,有必要定义一个函数来提供必要的填充:

代码语言:javascript
运行
复制
def row($i; $padding):
  . as $in
  | [range(0;$padding) | null] as $nulls
  | reduce range(0; length) as $ix 
      ([]; . + ($in[$ix][1][$i] // $nulls));

现在可以通过行(0;4)获得第一个数据行,通过行(1;4)获得第二个数据行,依此类推。

数据行的总数将通过map(.[1] | length) | max过滤中间数据结构得到;因此,可以通过将以下内容添加到前一个管道来获得数据行:

代码语言:javascript
运行
复制
| (map(.[1] | length) | max) as $rows
| range(0; $rows) as $r
| row($r; 4)
| @tsv

使用-r命令行选项和给定的示例,输出将是:

代码语言:javascript
运行
复制
393 720 203 49994   649 111 55400   877 748 5624    8746    7773
687 345 55005   1229996                 124 54  8847    5526

添加标头只是一个练习:-)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56468581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档