Создать массив из многомерного с помощью jq

#json #hierarchical-data #jq #data-extraction

#json #иерархический-данные #jq #извлечение данных

Вопрос:

Я хотел бы использовать json-процессор ‘jq’ для преобразования структуры json в массив простых объектов.

Моя структура выглядит так:

 {"nsgs": [
    {
        "comments": "text1",
        "properties": {
            "securityRules": [
                {
                    "name": "1",
                    "properties": {
                        "protocol": "TCP",
                        "sourcePortRange": "*"
                    }
                },
                {
                    "name": "2",
                    "properties": {
                        "protocol": "UDP",
                        "sourcePortRange": "*"
                    }
                }
            ]
        }
    },
    {
        "comments": "text2",
        "properties": {
            "securityRules": [
                {
                    "name": "3",
                    "properties": {
                        "protocol": "TCP",
                        "sourcePortRange": "*"
                    }
                },
                {
                    "name": "4",
                    "properties": {
                        "protocol": "UDP",
                        "sourcePortRange": "*"
                    }
                }
            ]
        }
    }
]}
  

И то, что я хочу получить, это:

 [
{ "comments": "text1",
  "name": "1",
  "protocol": "TCP",
  "sourcePortRange": "*"
},

{ "comments": "text1",
  "name": "2",
  "protocol": "UDP",
  "sourcePortRange": "*"
},

{ "comments": "text2",
  "name": "3",
  "protocol": "TCP",
  "sourcePortRange": "*"
},

{ "comments": "text2",
  "name": "4",
  "protocol": "UDP",
  "sourcePortRange": "*"
}
]
  

Я перепробовал множество подходов, но ничего не помогает.

Буду признателен за любую помощь.

Ответ №1:

Вот еще одно решение:

 .nsgs | map({comments}   (.properties.securityRules[] | {name} .properties))
  

Ответ №2:

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

 .nsgs
| map(.comments as $comments
      | .properties.securityRules[]
      | {comments: $comments,
         name, 
         protocol: .properties.protocol,
         sourcePortRange: .properties.sourcePortRange } )
  

Если вы хотите избежать повторения в последних двух строках, вы можете заменить последние четыре строки на:

       | {comments: $comments, name }
          (.properties | {protocol, sourcePortRange} ) )