根据块中另一个属性的值获取名称值

根据块中另一个属性的值获取名称值

使用jq,我想获取块的“name”值,其中“Media”属性(在.session.attributeList下)包含“node7000”字符串(在示例中,json第一个数组块与其匹配 - 有两个匹配:

“值”:“节点7000”

"value": "node7000 和 node8000"

预期 jq 输出为:

“17200站”

[{
    "name": "Station 17200",
    "attributes": [{
            "name": "EnableLog",
            "value": "1"
        }, {
            "name": "LogFont",
            "value": "0"
        }, {
            "name": "IdleTimer",
            "value": "30"
        }
    ],
    "session": [{
            "attributeList": [{
                    "name": "Launch",
                    "value": "1"
                }, {
                    "name": "Media",
                    "value": "node7000"
                }
            ]
        }, {
            "attributeList": [{
                    "name": "Group",
                    "value": "1"
                }, {
                    "name": "RMedia",
                    "value": "1"
                }
            ]
        }, {
            "attributeList": [{
                    "name": "Launch",
                    "value": ""
                }, {
                    "name": "Media",
                    "value": "node7000 and node8000"
                }
            ]
        }
    ]
},
{
    "name": "Station 17300",
    "attributes": [{
            "name": "EnableLog",
            "value": "1"
        }, {
            "name": "LogFont",
            "value": "0"
        }, {
            "name": "IdleTimer",
            "value": "30"
        }
    ],
    "session": [{
            "attributeList": [{
                    "name": "Launch",
                    "value": "1"
                }, {
                    "name": "Media",
                    "value": "node6000"
                }
            ]
        }, {
            "attributeList": [{
                    "name": "Group",
                    "value": "1"
                }, {
                    "name": "RMedia",
                    "value": "1"
                }
            ]
        }, {
            "attributeList": [{
                    "name": "Launch",
                    "value": ""
                }, {
                    "name": "Media",
                    "value": "node6001"
                }
            ]
        }
    ]
}]

答案1

jq解决方案:

jq '.[] | select([.session[].attributeList[] 
                   | .name == "Media" and (.value | contains("node7000"))
                 ] | any ).name' jsonfile
  • .[]- 迭代输入数组的所有元素(对象)
  • select(<condition>)<condition>- 如果返回该输入,则该函数将不改变其输入true,否则不产生输出
  • contains(element)- 过滤器生成true是否element完全包含在输入中
  • any- 过滤器将布尔值数组作为输入,true如果数组中的任何元素为true

输出:

"Station 17200"

答案2

这只是为了展示如何重写jqRomanPerekhrest 提出的表达方式以便函数any(generator; condition)的形式any用来:

.[] |
select(
        any(
                .session[].attributeList[];
                .name == "Media" and (.value | contains("node7000"))
        )
).name

这指示函数从顶级数组的每个元素中any提取所有值。然后,它将使用每个元素的给定条件表达式.session[].attributeList[]从这些元素创建一个布尔数组。attributeList如果任何布尔值是真的,然后选择顶级数组的该元素。name然后提取并打印密钥的值。

显然,如果您想让查询字符串node7000依赖于 shell 变量,那么您将使用--arg将其传递到表达式中:

query_string=node7000
jq --arg media "$query_string" '.[] | select(any(.session[].attributeList[]; .name == "Media" and (.value | contains($media)))).name' file.json

如果您想传递 PCRE 正则表达式而不是字符串,请更改contains($media)为。test($media)这还允许我们专门寻找例如node7000使用单词边界符号(\b),以避免出现误报子字符串与字符串匹配的风险,例如node70001

jq --arg media '\bnode7000\b' '.[] | select(any(.session[].attributeList[]; .name == "Media" and (.value | test($media)))).name' file.json

相关内容