Как составить таблицу вложенного файла JSON с помощью jq - PullRequest
0 голосов
/ 06 июня 2019

У меня есть следующий файл JSON, который я хотел бы проанализировать с помощью инструмента jq, который мне кто-то предложил, но я новичок в этом.Есть 3 родительских узла с одинаковыми именами детей.Родительские узлы - это MNR, GNR и MSNR, и у каждого из них есть дочерние узлы с именами N1, N2, NR_i, NR_f.

{
  "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"
              }
            }
          }
        }
      }
    }
  }
}

. С этим кодом я получаю следующее

.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"
      }
    }
  }
]

Ис помощью этих команд я получаю столбцы отдельных значений для каждого дочернего элемента, а другие - ноль.

.. | .N1?
.. | .N2?
.. | .NR_i?
.. | .NR_f?

Я далек от желаемого результата, поскольку хотел бы извлечь дочерние элементы для каждого родителя и табулировать вФорма ниже.

+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
|             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 |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+ 

Может кто-нибудь помочь мне с этим.Заранее спасибо.

1 Ответ

2 голосов
/ 06 июня 2019

Поскольку характер входного JSON был дан только в качестве примера, давайте начнем с определения фильтра для линеаризации .NR:

# Produce a stream of arrays
def linearize:
  if type == "array" then .[] | linearize
  else [ .N1, .N2, .SNR.NR_i, .SNR.NR_f]
  end;

Соответствующие данные теперь могут быть извлечены при сохранении верхнегоГруппы уровней следующим образом:

.Main.List.SubList.ND.RiS.RiN.NSE14
| [to_entries[]
| [.key]
  + [.value | .. | objects | select(has("NR")) | .NR | [ linearize ]] ]

Поскольку входной JSON не является однородным, это поможет обеспечить однородность, дополнив вышеуказанный конвейер следующим отображением:

| map(if length > 2 then [.[0], [.[1:][][]]] else . end)

Это приведет кодин массив JSON, структурированный следующим образом:

[["MNRs",[["393","720","203","49994"]],[["687","345","55005","1229996"]]],
 ["GNRs", ...

Чтобы получить первую строку данных таблицы из этого промежуточного результата, целесообразно определить функцию, которая обеспечит необходимое заполнение:

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;таким образом, строки данных можно получить, прикрепив к предыдущему конвейеру следующее:

| (map(.[1] | length) | max) as $rows
| range(0; $rows) as $r
| row($r; 4)
| @tsv

Используя параметр командной строки -r и данный образец, вы получите:

393 720 203 49994   649 111 55400   877 748 5624    8746    7773
687 345 55005   1229996                 124 54  8847    5526

Добавление заголовков оставлено в качестве упражнения: -)

...