jq를 사용하여 특정 값을 가진 다른 속성을 포함하는 객체의 속성 업데이트

jq를 사용하여 특정 값을 가진 다른 속성을 포함하는 객체의 속성 업데이트

jq를 사용하면 다른 속성에 특정 값이 포함된 객체의 속성 값을 업데이트할 수 있나요?

아래 예에서는 "keyname" = "foo"인 모든 개체의 "value" 속성 값을 설정하려고 합니다.

샘플 .json 파일은 다음과 같습니다.

"root" : {
  "instances": [
    {
      "name": "1",
      "configs": [
        {
          "keyname": "foo",
          "value": "" // <- update/set this
        },
        {
          "keyname": "barrr",
          "value": "barrrr"
        }
      ]
    },
    {
      "name": "2",
      "configs": [
        {
          "keyname": "foo",
          "value": "" // <- update/set this
        },
        {
          "keyname": "buzzz",
          "value": "buzzz"
        }
      ]
    }
  ]
}

나는 이것을 시도했지만 성공하지 못했습니다. 배열이 문자열이 아니라는 오류가 발생했습니다.

jq '(.root.instances.configs[] | select(.keyname==foo)).value = foo'

답변1

JSON 문서의 형식이 올바르다고 가정하면 표시된 예에는 여러 문제가 포함되어 있으므로 그렇지 않습니다.

$ cat file
{
  "root": {
    "instances": [
      {
        "name": "1",
        "configs": [
          {
            "keyname": "foo",
            "value": ""
          },
          {
            "keyname": "barrr",
            "value": "barrrr"
          }
        ]
      },
      {
        "name": "2",
        "configs": [
          {
            "keyname": "foo",
            "value": ""
          },
          {
            "keyname": "buzzz",
            "value": "buzzz"
          }
        ]
      }
    ]
  }
}
$ jq '( .root.instances[].configs[] | select(.keyname == "foo") ).value |= "foo"' file
{
  "root": {
    "instances": [
      {
        "name": "1",
        "configs": [
          {
            "keyname": "foo",
            "value": "foo"
          },
          {
            "keyname": "barrr",
            "value": "barrrr"
          }
        ]
      },
      {
        "name": "2",
        "configs": [
          {
            "keyname": "foo",
            "value": "foo"
          },
          {
            "keyname": "buzzz",
            "value": "buzzz"
          }
        ]
      }
    ]
  }
}

jq표현식은 키 값을 .valuestring 으로 업데이트합니다 foo. 업데이트된 키는 항목 중 하나에서 선택됩니다 .root.instances[].configs[]. 이는 .root.instances배열이며 .configs각 요소의 각 항목도 배열입니다. 이 문은 문자열을 사용하여 select()키를 테스트합니다..keynamefoo

쿼리 키와 새 값 변수를 만드는 과정은 다음과 같습니다.

jq  --arg querykey 'foo' \
    --arg newval 'The train said "choo choo"' \
    '( .root.instances[].configs[] | select(.keyname == $querykey) ).value |= $newval' file

그러면 및 라는 두 개의 내부 jq변수가 생성됩니다. 예를 들어 위와 같이 큰따옴표가 포함될 수 있도록 해당 값이 올바르게 인코딩됩니다.$querykey$newval$newval

관련 정보