JQ检查给定的参数数组中是否存在值

3

我有一个简单的 JQ 过滤器,可以根据“Key”更新数组中的某些值。例如,这是我的输入:

[
    {
        "Key": "IDontCare",
        "Value": "something"
    },
    {
        "Key": "Tag1",
        "Value": "123-456"
    },
    {
        "Key": "Tag2",
        "Value": "121-717"
    }
]

我想要将这两个标签的值更新为一个新值(相同的值),所以我有了这个命令,它能够操作成功:
jq --arg NEW_VALUE '987-654' \
    '[.[] |= if(.Key=="Tag1" or .Key=="Tag2") then (.Value=$NEW_VALUE) else . end]'

我希望在不同的运行中更新不同的标签,并将它们作为另一个参数传递。但是不确定如何更改if()以从参数中查找标签。

我尝试了类似这样的东西,但显然不是正确的方式:

jq --argjson TAGS '["Tag1","Tag2"]' --arg NEW_VALUE '987-654' \
    '[.[] |= if(.Key|in($TAGS)) then (.Value=$NEW_VALUE) else . end]'

有什么想法吗?

2个回答

2

使用jq 1.5或更高版本

jq --arg NEW_VALUE '987-654' --argjson TAGS '["Tag1","Tag2"]' '
   def IN(s): first((s == .) // empty) // false;
   map(if .Key | IN($TAGS[]) then .Value = $NEW_VALUE else . end)
'

如果你使用 jq 1.6 版本,显然可以省略 IN/1 的定义。

使用 jq 1.4 或更高版本

jq --arg NEW_VALUE '987-654' --arg TAGS '["Tag1","Tag2"]' '
   ($TAGS|fromjson) as $TAGS
   | map(if [.Key == $TAGS[]]|any then .Value = $NEW_VALUE else . end)
' 

2
您可以使用IN来判断值是否在列表中,并使用选择语句进行更简单的更新赋值。
jq --arg NEW_VALUE '987-654' --argjson TAGS '["Tag1","Tag2"]' '
   map(select( .Key | IN($TAGS[] ) ).Value |= $NEW_VALUE )' json

太好了!JQ 1.5有没有类似简洁的方法?它显示jq: error: IN/1 is not defined at <top-level> - MLu
@MLu:IN 就是这个简单的函数 - 你可以使用它代替 - https://github.com/stedolan/jq/blob/master/src/builtin.jq#L274 - Inian
所以我将其更改为 select( .Key | any($TAGS[] == .; .) ),但在1.5中仍然无法工作。不过,在1.6中仍然有效。 - MLu
@MLu:你可以从这里采用一种方法-https://dev59.com/h1gQ5IYBdhLWcg3wIQZB - Inian
我之前看过那个答案,但还是没搞明白。我们会更新我们的管道到 jq 1.6,这样会更容易些。我承认对我来说 jq 是一种神奇的东西,我只是复制粘贴而已,并没有太多理解。我知道,我知道... - MLu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接