Jq迭代数组对象以创建新的json对象

时间:2018-05-09 06:45:41

标签: json slice jq

我一直在思考和寻找很长一段时间,但我没有找到我正在寻找的东西。    我正在使用JQ来解析tshark(-ek)json输出,但我是一个jq newby    当一个帧是多值时,我有一个类似于这个的JSON:

 {
      "timestamp": "1525627021656",
      "layers": {
        "frame_time_epoch": [
          "1525627021.656417000"
        ],
        "ip_src": [
          "10.10.10.10"
        ],
        "ip_src_host": [
          "test"
        ],
        "ip_dst": [
          "10.10.10.11"
        ],
        "ip_dst_host": [
          "dest_test"
        ],
        "diameter_Event-Timestamp": [
          "May  6, 2018 19:17:02.000000000 CEST",
          "May  6, 2018 19:17:02.000000000 CEST"
        ],
        "diameter_Origin-Host": [
          "TESTHOST",
          "TESTHOST"
        ],
        "diameter_Destination-Host": [
          "DESTHOST",
          "DESTHOST"
        ],
        "diameter_CC-Request-Type": [
          "2",
          "2"
        ],
        "diameter_CC-Request-Number": [
          "10",
          "3"
        ],
        "diameter_Rating-Group": [
          "9004",
          "9001"
        ],
        "diameter_Called-Station-Id": [
          "testing",
          "testing"
        ],
        "diameter_User-Name": [
          "testuser",
          "testuser"
        ],
        "diameter_Subscription-Id-Data": [
          "66666666666",
          "77777777777"
        ],
        "gtp_qos_version": [
          "0x00000008",
          "0x00000005"
        ],
        "gtp_qos_max_dl": [
          "8640",
          "42"
        ],
        "diameter_Session-Id": [
          "test1;sessionID1;test1",
          "test2;sessionID2;test2"
        ]
      }
    }

正如您所看到的,许多键都是数组,我想迭代它们以在结果中创建不同的json对象:

{
    "frame_time_epoch": [
      "1525627021.656417000"
    ],
    "ip_src": [
      "10.10.10.10"
    ],
    "ip_src_host": [
      "test"
    ],
    "ip_dst": [
      "10.10.10.11"
    ],
    "ip_dst_host": [
      "dest_test"
    ],
    "diameter_Event-Timestamp": [
      "May  6, 2018 19:17:02.000000000 CEST"
    ],
    "diameter_Origin-Host": [
      "TESTHOST"
    ],
    "diameter_Destination-Host": [
      "DESTHOST"
    ],
    "diameter_CC-Request-Type": [
      "2"
    ],
    "diameter_CC-Request-Number": [
      "3"
    ],
    "diameter_Rating-Group": [
      "9001"
    ],
    "diameter_Called-Station-Id": [
      "testing"
    ],
    "diameter_User-Name": [
      "testuser"
    ],
    "diameter_Subscription-Id-Data": [
      "77777777777"
    ],
    "gtp_qos_version": [
      "0x00000005"
    ],
    "gtp_qos_max_dl": [
      "42"
    ],
    "diameter_Session-Id": [
      "test2;sessionID2;test2"
    ]
  }
 {
    "frame_time_epoch": [
      "1525627021.656417000"
    ],
    "ip_src": [
      "10.10.10.10"
    ],
    "ip_src_host": [
      "test"
    ],
    "ip_dst": [
      "10.10.10.11"
    ],
    "ip_dst_host": [
      "dest_test"
    ],
    "diameter_Event-Timestamp": [
      "May  6, 2018 19:17:02.000000000 CEST"
    ],
    "diameter_Origin-Host": [
      "TESTHOST"
    ],
    "diameter_Destination-Host": [
      "DESTHOST"
    ],
    "diameter_CC-Request-Type": [
      "2"
    ],
    "diameter_CC-Request-Number": [
      "10"
    ],
    "diameter_Rating-Group": [
      "9004"
    ],
    "diameter_Called-Station-Id": [
      "testing"
    ],
    "diameter_User-Name": [
      "testuser"
    ],
    "diameter_Subscription-Id-Data": [
      "66666666666"
    ],
    "gtp_qos_version": [
      "0x00000008"
    ],
    "gtp_qos_max_dl": [
      "8640"
    ],
    "diameter_Session-Id": [
      "test1;sessionID1;test1"
    ]
  }

另一个手工制作的例子: INPUT:

{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value1" , "value2"],
    "any_key_name": ["value4" ,"value5"]
}
{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value6" , "value7", "value8"],
    "any_key_name": ["value9" ,"value10" , "value11"]
}

期望的输出:

{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value1"],
    "any_key_name": ["value4"],
}
{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value2"],
    "any_key_name": ["value5"],
}
{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value6"],
    "any_key_name": ["value9"],
}
{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value7"],
    "any_key_name": ["value10"],
}
{
    "key_single": ["single_value"],
    "key2": ["single_value"],
    "multiple_value_key": ["value8"],
    "any_key_name": ["value11"],
}
你能帮助我吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

看起来你想要依次选择所选数组的第i个元素。使用您的第二个示例,可以这样做:

range(0; .multiple_value_key|length) as $i
| . + { multiple_value_key: [.multiple_value_key[$i]],
        any_key_name:       [.any_key_name[$i]] }

紧凑形式的输出:

{"key_single":["single_value"],"key2":["single_value"],"multiple_value_key":["value1"],"any_key_name":["value4"]}
{"key_single":["single_value"],"key2":["single_value"],"multiple_value_key":["value2"],"any_key_name":["value5"]}
{"key_single":["single_value"],"key2":["single_value"],"multiple_value_key":["value6"],"any_key_name":["value9"]}
{"key_single":["single_value"],"key2":["single_value"],"multiple_value_key":["value7"],"any_key_name":["value10"]}
{"key_single":["single_value"],"key2":["single_value"],"multiple_value_key":["value8"],"any_key_name":["value11"]}

答案 1 :(得分:0)

这是#34;评论"中描述的问题的简单解决方案,尽管如此 输出与Q中显示的略有不同。

为清楚起见,定义了一个辅助函数来生成一个对象的第i个切片, 也就是说,对于数组长度大于1的所有数组值键, 该值将替换为数组中的$ i-th项。

def slice($i):
    map_values(if (type == "array" and length>1)
               then [.[$i]]
               else . end);

解决方案就是:

.layers
| range(0;  [.[] | length] | max) as $i
| slice($i)

输出

{
  "frame_time_epoch": [
    "1525627021.656417000"
  ],
  "ip_src": [
    "10.10.10.10"
  ],
  "ip_src_host": [
    "test"
  ],
  "ip_dst": [
    "10.10.10.11"
  ],
  "ip_dst_host": [
    "dest_test"
  ],
  "diameter_Event-Timestamp": [
    "May  6, 2018 19:17:02.000000000 CEST"
  ],
  "diameter_Origin-Host": [
    "TESTHOST"
  ],
  "diameter_Destination-Host": [
    "DESTHOST"
  ],
  "diameter_CC-Request-Type": [
    "2"
  ],
  "diameter_CC-Request-Number": [
    "10"
  ],
  "diameter_Rating-Group": [
    "9004"
  ],
  "diameter_Called-Station-Id": [
    "testing"
  ],
  "diameter_User-Name": [
    "testuser"
  ],
  "diameter_Subscription-Id-Data": [
    "66666666666"
  ],
  "gtp_qos_version": [
    "0x00000008"
  ],
  "gtp_qos_max_dl": [
    "8640"
  ],
  "diameter_Session-Id": [
    "test1;sessionID1;test1"
  ]
}
{
  "frame_time_epoch": [
    "1525627021.656417000"
  ],
  "ip_src": [
    "10.10.10.10"
  ],
  "ip_src_host": [
    "test"
  ],
  "ip_dst": [
    "10.10.10.11"
  ],
  "ip_dst_host": [
    "dest_test"
  ],
  "diameter_Event-Timestamp": [
    "May  6, 2018 19:17:02.000000000 CEST"
  ],
  "diameter_Origin-Host": [
    "TESTHOST"
  ],
  "diameter_Destination-Host": [
    "DESTHOST"
  ],
  "diameter_CC-Request-Type": [
    "2"
  ],
  "diameter_CC-Request-Number": [
    "3"
  ],
  "diameter_Rating-Group": [
    "9001"
  ],
  "diameter_Called-Station-Id": [
    "testing"
  ],
  "diameter_User-Name": [
    "testuser"
  ],
  "diameter_Subscription-Id-Data": [
    "77777777777"
  ],
  "gtp_qos_version": [
    "0x00000005"
  ],
  "gtp_qos_max_dl": [
    "42"
  ],
  "diameter_Session-Id": [
    "test2;sessionID2;test2"
  ]
}