我过去曾问过类似的问题,但我很难使该解决方案适应这个问题。
我有以下 json 数组:
$ jq <<<"$json"
[
{
"id": "node1"
},
{
"id": "node2"
},
{
"id": "node3"
}
]
我想向每个节点添加一个键/值或修改它(如果它已经存在)。我可以这样做:
$ jq '.[] | select(.id == "node2") += {status: "fail"}' <<<"$json"
{
"id": "node1"
}
{
"id": "node2",
"status": "fail"
}
{
"id": "node3"
}
但请注意,外部数组消失了,因此当我尝试在脚本中实现此解决方案时,它失败了。
#!/usr/bin/env bash
[[ $DEBUG == true ]] && set -x
nodes=(node1 node2 node3)
json='[{"id": "node1"},{"id": "node2"},{"id": "node3"}]'
for node in "${nodes[@]}"; do
if [[ $node == node2 ]]; then
status=fail
else
status=pass
fi
json=$(jq --arg status "$status" --arg node "$node" '.[] | select(.id == $node) += {status: $status}' <<<"$json")
done
错误:
$ ./script.sh
jq: error (at <stdin>:4): Cannot index string with string "id"
jq: error (at <stdin>:7): Cannot index string with string "id"
jq: error (at <stdin>:10): Cannot index string with string "id"
有没有办法可以修改这些 json 对象,同时保留整体结构?
.[]
一旦您从with中选择了一个元素select()
,这就是您剩下的唯一数据以及最后将输出的内容。相反,使用
map()
对顶级数组的每个元素应用(可能的)修改:或者可能更整洁,用更少的大括号,
复制 shell 循环以
jq
避免多次调用jq
:--args
或者,使多个节点失败,并在命令行上列出每个失败的节点(请注意最后的非正统但必要的放置):