나는 물었다유제하지만 이 문제에 대한 해결책을 적용하는 데 문제가 있습니다.
다음과 같은 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 개체를 수정하는 방법이 있습니까?
답변1
.[]
에서 요소를 선택하면 select()
그것이 남은 유일한 데이터이며 마지막에 출력되는 내용입니다.
대신 다음 map()
을 사용하여 최상위 배열의 각 요소에 (가능한) 수정 사항을 적용하십시오.
$ jq --arg id node2 --arg status fail 'map(select(.id == $id) += { status: $status } )' file
[
{
"id": "node1"
},
{
"id": "node2",
"status": "fail"
},
{
"id": "node3"
}
]
아니면 괄호 수가 적어서 더 깔끔할 수도 있습니다.
$ jq --arg id node2 --arg status fail 'map(select(.id == $id).status = $status)' file
[
{
"id": "node1"
},
{
"id": "node2",
"status": "fail"
},
{
"id": "node3"
}
]
jq
여러 호출을 피하기 위해 쉘 루프를 복사하십시오 jq
.
$ jq --arg failnode node2 'map(.status = if .id == $failnode then "fail" else "pass" end)' file
[
{
"id": "node1",
"status": "pass"
},
{
"id": "node2",
"status": "fail"
},
{
"id": "node3",
"status": "pass"
}
]
--args
또는 여러 노드에 장애가 발생하고 장애가 발생한 각 노드를 명령줄에 나열합니다(정통적이지는 않지만 끝에 필요한 배치에 유의하세요).
$ jq 'map(.status = if (.id|IN($ARGS.positional[])) then "fail" else "pass" end)' file --args node1 node2
[
{
"id": "node1",
"status": "fail"
},
{
"id": "node2",
"status": "fail"
},
{
"id": "node3",
"status": "pass"
}
]