如何让 jq 选择名称值对

How to make jq to pick name value pairs

可能或多或少与 How to get JQ name/value pair from nested (array?) response? 相同,但这个问题和例子比我要问的要复杂得多 --

按照 https://jqplay.org/s/jyKBnpx9NYX
中的方式提供输入 jason 把.QueryString, .Params下的所有name/value对挑出来放入同一个未嵌套数组

例如,输入

{
    "Some": "Random stuff",
    "One": {
        "QueryString": [
           { "Name": "IsOrdered",    "Value": "1"              },
           { "Name": "TimeStamp",    "Value": "11654116426247" }
        ]
    },
    "Two": {
        "QueryString": [
           { "Name": "IsOrdered",    "Value": "1"              },
           { "Name": "TimeStamp",    "Value": "11654116426247" }
        ]
    },
    "Params": [
       { "Name": "ClassName",    "Value": "PRODUCT"        },
       { "Name": "ListID",       "Value": "Products"       },
       { "Name": "Mode ",        "Value": "1"              },
       { "Name": "Dept"  ,       "Value": "5"              },
       { "Name": "HasPrevOrder", "Value": ""               }
    ],
    "And": {
        "QueryString":[]
    },
    "More": "like",
    "More+": "this"
}

输出将是:

  [
    {
      "Name": "IsOrdered",
      "Value": "1"
    },
    {
      "Name": "TimeStamp",
      "Value": "11654116426247"
    },
    {
      "Name": "IsOrdered",
      "Value": "1"
    },
    {
      "Name": "TimeStamp",
      "Value": "11654116426247"
    },
    {
      "Name": "ClassName",
      "Value": "PRODUCT"
    },
    {
      "Name": "ListID",
      "Value": "Products"
    },
  ...
  ],

没有任何空数组输出([]),同时保留数组中的重复值。

我试图通过从

更改 jq 表达式来删除空数组输出 ([])

[( .. | objects | ( .QueryString, .Params ) | select( . != null) )]

[( .. | objects | ( .QueryString, .Params ) | select( . != null && . != []) )]

但是失败了。

最终的输出也需要取消嵌套到一个数组中。

额外问题:是否可以像下面这样在一行中输出每个 name/value 对?

       { "Name": "IsOrdered",    "Value": "1"              },
       { "Name": "TimeStamp",    "Value": "11654116426247" },
       { "Name": "IsOrdered",    "Value": "1"              },
       { "Name": "TimeStamp",    "Value": "11654116426247" },

&& 必须替换为 and。在结果上,您可以使用 | flatten 将“对象数组的数组”转换为“对象数组”。

奖励 A:将 jq-c/--compact-output 标志与 | flatten[] 一起使用,而不仅仅是 | flatten.

一起:

jq -c '
[
    ..
    | objects
    | ( .QueryString, .Params )
    | select(. != null and . != [])
]
| flatten[]' input.json

虽然这个表达式可以简化为.. | objects | .QueryString[]?, .Params[]? 输出为:

{"Name":"ClassName","Value":"PRODUCT"}
{"Name":"ListID","Value":"Products"}
{"Name":"Mode ","Value":"1"}
{"Name":"Dept","Value":"5"}
{"Name":"HasPrevOrder","Value":""}
{"Name":"IsOrdered","Value":"1"}
{"Name":"TimeStamp","Value":"11654116426247"}
{"Name":"IsOrdered","Value":"1"}
{"Name":"TimeStamp","Value":"11654116426247"}

要获取 Name/Value 个对象,每行一个,您可以使用:

jq -c '.. | objects | (.QueryString, .Params) | .. | objects | select( .Name and .Value)' 

或更傲慢:

    jq -c '.. | objects | select( .Name and .Value)'