为什么添加jq参数不会更改值

时间:2019-04-19 21:32:07

标签: bash jq

我正在编写一个bash脚本,遇到了这个问题。当我传递jq --arg标志时,它不会更新该值。但是,当我在没有--arg标志的情况下对值进行硬编码时,就可以了。

我已经在脚本中尝试过此操作,并且还在终端中以两种方式(带有或不带有参数标志)直接尝试了此操作。使用不会更新值。如果没有,则更新值。

echo "${JSON}"
[
  {
    "type": "portRule",
    "hostname": "fizz.buzz",
    "protocol": "https",
    "serviceId": "1s1495",
    "sourcePort": 443,
    "targetPort": 80
  },
  {
    "type": "portRule",
    "hostname": "foo.bar",
    "serviceId": "1s1499",
    "sourcePort": 443,
    "targetPort": 8082
  }
]

作品

jq '.[] | select((.hostname=="foo.bar") and (.targetPort==8082)).serviceId = "123"' <<<"${JSON}" | jq -s

输出

[
  {
    "type": "portRule",
    "hostname": "fizz.buzz",
    "protocol": "https",
    "serviceId": "1s1495",
    "sourcePort": 443,
    "targetPort": 80
  },
  {
    "type": "portRule",
    "hostname": "foo.bar",
    "serviceId": "123",
    "sourcePort": 443,
    "targetPort": 8082
  }
]

不起作用

jq --arg host "foo.bar" --arg port "8082" --arg id "123" '.[] | select((.hostname==$host) and (.targetPort==$port)).serviceId = $id' <<<"${JSON}" | jq -s

输出

[
  {
    "type": "portRule",
    "hostname": "fizz.buzz",
    "protocol": "https",
    "serviceId": "1s1495",
    "sourcePort": 443,
    "targetPort": 80
  },
  {
    "type": "portRule",
    "hostname": "foo.bar",
    "serviceId": "1s1499",
    "sourcePort": 443,
    "targetPort": 8082
  }
]

我将注意到,我希望甚至可以用环境变量代替参数值,而不是如示例所示的字符串。但是我已经测试了两种方法,结果相同。

那么我做错什么了吗?还是这是jq的错误(可能不是)。

预期结果。它会使用--arg标志更新json中的值,就像不使用它并对其进行硬编码一样。

1 个答案:

答案 0 :(得分:2)

使用--arg传递给jq的变量都转换为字符串,您需要使用--argjson传递整数。

jq --arg host "foo.bar" --argjson port "8082" --arg id "123" '.[] | select((.hostname==$host) and (.targetPort==$port)).serviceId = $id' <<<"${JSON}" | jq -s

作为旁注,您无需调用jq两次,只需使用map

jq 'map(select(.hostname==$host and .targetPort==$port).serviceId=$id)' --arg host "foo.bar" --argjson port 8082 --arg id "123" <<<"$JSON"