이름이 다음과 같은 JSON 파일이 있습니다 pool.json
.
{
"AllocateActions": {},
"Available": true,
"Description": "Pool for nodes in cluster - {{CLUSTER_NAME}}",
"Endpoint": "",
"EnterActions": {
"AddProfiles": [
"{{RC_JOIN_PROFILE}}",
"image-deploy-profile",
"rc-controlplane-profile",
"rc-etcd-profile"
],
"Workflow": "rc-image-deploy"
},
"Errors": [],
"ExitActions": {
"RemoveProfiles": [
"{{RC_JOIN_PROFILE}}",
"image-deploy-profile"
],
"Workflow": "discover-base"
},
"Meta": {
"color": "black",
"feature-flags": "sane-exit-codes",
"icon": "object ungroup outline",
"title": "User added"
},
"ReadOnly": true,
"ReleaseActions": {},
"Validated": true
}
jq
내 Bash 스크립트에서는 다음 JSON 자리 표시자에 값을 전달하는 데 사용합니다 .
NODE_JSON=$(jq --arg RC_JOIN_PROFILE "$RC_JOIN_PROFILE" --arg CLUSTER_NAME "$CLUSTER_NAME" '.Description = "'$CLUSTER_NAME'"| .ExitActions.RemoveProfiles = [ "'$RC_JOIN_PROFILE'" ] | .EnterActions.AddProfiles = [ "'$RC_JOIN_PROFILE'" ]' pool.json)
RC_JOIN_PROFILE="test-profile"
합계를 전달하면 CLUSTER_NAME="test-cluster"
최종 JSON은 다음과 같을 것으로 예상됩니다.
{
"AllocateActions": {},
"Available": true,
"Description": "Pool for nodes in cluster - test-cluster",
"Endpoint": "",
"EnterActions": {
"AddProfiles": [
"test-profile",
"image-deploy-profile",
"rc-controlplane-profile",
"rc-etcd-profile"
],
"Workflow": "rc-image-deploy"
},
"Errors": [],
"ExitActions": {
"RemoveProfiles": [
"test-profile",
"image-deploy-profile"
],
"Workflow": "discover-base"
},
"Meta": {
"color": "black",
"feature-flags": "sane-exit-codes",
"icon": "object ungroup outline",
"title": "User added"
},
"ReadOnly": true,
"ReleaseActions": {},
"Validated": true
}
그러나 아래 JSON을 얻습니다.
{
"AllocateActions": {},
"Available": true,
"Description": "test-cluster",
"Endpoint": "",
"EnterActions": {
"AddProfiles": [
"test-profile",
],
"Workflow": "rc-image-deploy"
},
"Errors": [],
"ExitActions": {
"RemoveProfiles": [
"test-profile",
],
"Workflow": "discover-base"
},
"Meta": {
"color": "black",
"feature-flags": "sane-exit-codes",
"icon": "object ungroup outline",
"title": "User added"
},
"ReadOnly": true,
"ReleaseActions": {},
"Validated": true
}
.ExitActions.AddPofiles
, 및 .ExitActions.RemoveProfiles
의 기존 값을 .Description
전달된 값으로 덮어썼습니다. 전달된 값이 있는 기존 값을 원합니다. 많은 시나리오를 시도했지만 아무것도 작동하지 않습니다. 누구든지 도와줄 수 있나요?
답변1
코드에는 세 가지 주요 문제가 있습니다.
jq
전혀 사용되지 않는 변수를 정의했습니다 .- 너놓다업데이트하는 대신 배열을 값으로 변경하십시오.
- 템플릿 자리표시자를 일치시키려고 하지 마세요.
대신 값을 내부 jq
변수에 전달하고, sub()
템플릿 자리 표시자를 적절한 값으로 바꾸고, |=
연산자를 사용하여 필요한 데이터 업데이트를 단순화합니다( a |= expression
와 동일 a = (a | expression)
).
jq --arg clustername "$CLUSTER_NAME" --arg profilename "$RC_JOIN_PROFILE" '
.Description |= sub("{{CLUSTER_NAME}}"; $clustername) |
.EnterActions.AddProfiles |= map(sub("{{RC_JOIN_PROFILE}}"; $profilename)) |
.ExitActions.RemoveProfiles |= map(sub("{{RC_JOIN_PROFILE}}"; $profilename))' pool.json
여기에서는 템플릿 자리 표시자가 있는 입력 JSON의 세 비트가 업데이트되어 sub()
자리 표시자가 적절한 값으로 대체됩니다. 두 배열은 sub()
각 요소에 대한 호출을 매핑하여 처리되므로 배열에서 자리 표시자의 위치에 의존할 필요가 없습니다.
배열의 첫 번째 요소에만 영향을 미치려면 다음을 사용하세요.
.ExitActions.RemoveProfiles[0] |= sub("{{RC_JOIN_PROFILE}}"; $profilename)
아니면 그냥 원한다면분배하다배열의 첫 번째 요소 값
.ExitActions.RemoveProfiles[0] = $profilename
(첫 번째 배열과 유사하지만 사용되지 않음 map()
)
주어진 데이터에 대한 실행 예시:
$ CLUSTER_NAME='Test Cluster Name "Charlie"'
$ RC_JOIN_PROFILE='Test RC Join Profile "Matilda"'
$ jq --arg clustername "$CLUSTER_NAME" --arg profilename "$RC_JOIN_PROFILE" '.Description |= sub("{{CLUSTER_NAME}}"; $clustername) | .EnterActions.AddProfiles |= map(sub("{{RC_JOIN_PROFILE}}"; $profilename)) | .ExitActions.RemoveProfiles |= map(sub("{{RC_JOIN_PROFILE}}"; $profilename))' pool.json
{
"AllocateActions": {},
"Available": true,
"Description": "Pool for nodes in cluster - Test Cluster Name \"Charlie\"",
"Endpoint": "",
"EnterActions": {
"AddProfiles": [
"Test RC Join Profile \"Matilda\"",
"image-deploy-profile",
"rc-controlplane-profile",
"rc-etcd-profile"
],
"Workflow": "rc-image-deploy"
},
"Errors": [],
"ExitActions": {
"RemoveProfiles": [
"Test RC Join Profile \"Matilda\"",
"image-deploy-profile"
],
"Workflow": "discover-base"
},
"Meta": {
"color": "black",
"feature-flags": "sane-exit-codes",
"icon": "object ungroup outline",
"title": "User added"
},
"ReadOnly": true,
"ReleaseActions": {},
"Validated": true
}
jq
명령줄에 정의된 변수를 사용하면 clustername
문자열에 대한 참조를 올바르게 처리할 수 있습니다 .profilename
--arg
jq