简体   繁体   English

jq:选择而不从数组中删除项目

[英]jq: select without dropping items from array

I have a JSON file which looks like this (a rough schema):我有一个看起来像这样的 JSON 文件(一个粗略的模式):

[{
    "custom_variables": [
        {
            "name": "xxx",
            "value": "xxx"
        },
        {
            "name": "xxx",
            "value": "xxx"
        },
        {
            "name": "profile_id",
            "value": "123"
        }
    ],
    // many fields
    "xxx": "xxx",
    "xxx": "xxx",
    "xxx": "xxx"
}]

I am using jq to extract all the fields from the top level object.我正在使用 jq 从顶级对象中提取所有字段。 The custom_variables field constains an array of objects with name and value. custom_variables 字段包含具有名称和值的对象数组。

I want to extract a specific object from custom_variables, given its name.我想从 custom_variables 中提取一个特定的对象,给定它的名字。

So what I am doing is this:所以我正在做的是:

jq 'map(
    {
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .custom_variables | .[] | select(.name == "variable_name")
    } 
)'

It almost works;它几乎有效; it gets the variable I want when it exists, but when it doesn't (or if custom_variables itself doesn't) it will drop the whole top-level object.它在存在时获取我想要的变量,但是当它不存在时(或者如果 custom_variables 本身不存在),它将删除整个顶级对象。 So in the end I am getting less objects then I put into the script.所以最后我得到的对象比我放入脚本的要少。

How can I just return null if I don't find that field but still keep the rest of the data?如果我没有找到该字段但仍保留其余数据,我怎么能只返回 null?

Use the alternative operator ( // ) to transform a stream of zero elements (such as those which can be generated by select or .[] ) into a value:使用替代运算符 ( // ) 将零元素流(例如可以由select.[]生成的那些)转换为值:

jq 'map(
    {
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .custom_variables | .[] | select(.name == "variable_name") // null
    } 
)'

This will have .xxx be null when there is a zero-element stream on the left side of // .//左侧有一个零元素流时,这将使.xxxnull

You can, of course, place the alternative operator at a different position to capture the zero-element stream at an earlier or later stage, such as at the object level:当然,您可以将替代运算符放在不同的位置,以便在更早或更晚的阶段捕获零元素流,例如在对象级别:

jq 'map(
    {
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .xxx, 
        xxx: .custom_variables | .[] | select(.name == "variable_name")
    } // {}
)'

This works, but it looks ugly.这有效,但看起来很难看。 Any better solutions?有什么更好的解决方案吗?

custom_variables: (if (.custom_variables | length > 0) 
            then (.custom_variables | .[]? | select(.name == "variable_name") | .value | scan("\\d+"))
            else null
            end)

The following does what you've indicated you want, as best as I can understand your requirements.尽我所能理解您的要求,以下内容可以满足您的要求。

map( if .custom_variables
     then .custom_variables |= (map(select(.name == "variable_name") | .value)
                                | .[0]) 
     else .
     end )

Example input:示例输入:

[{
    "custom_variables": [
        {
            "name": "xxx",
            "value": "xxx"
        },
        {
            "name": "xxx",
            "value": "xxx"
        },
        {
            "name": "variable_name",
            "value": "123"
        }
    ],
    "xxx1": "xxx",
    "xxx2": "xxx",
    "xxx3": "xxx"
},

{
    "yyy1": "yyy",
    "yyy2": "yyy",
    "yyy3": "yyy"
}
]

Output:输出:

[
  {
    "custom_variables": "123",
    "xxx1": "xxx",
    "xxx2": "xxx",
    "xxx3": "xxx"
  },
  {
    "yyy1": "yyy",
    "yyy2": "yyy",
    "yyy3": "yyy"
  }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM