with_entries 메소드를 사용하여 jq를 통해 키 이름을 재귀적으로 변경할 수 있습니까?

with_entries 메소드를 사용하여 jq를 통해 키 이름을 재귀적으로 변경할 수 있습니까?

다음 JSON 파일이 있다고 가정해 보겠습니다.

[
  {
    "name1": "fruits",
    "name2": "cars",
    "name3": "houses"
  }
]

jq다음과 같이 값의 이름을 바꾸는 데 사용할 수 있다는 것을 알고 있습니다 .

jq '[.[] | .["newname1"] = .name1 | del(.name1)]' file

이것은 잘 작동하며 더 복잡한 JSON 구조에서도 변경할 수 있습니다... 그러나 이것은 제가 변경하려는 키에 대한 매우 명확한 설명입니다. 동일한 작업을 수행하는 또 다른 방법은 다음 명령을 사용하는 것입니다.

jq 'map(with_entries(if .key == "name1" then .key = "newname1" else . end))' file 

JSON(객체 배열) 내에서 특정 이름을 가진 모든 키를 확인하고 변경하는 방법은 다음과 같습니다. key이 경우 명시적으로 선언된 이름이 필요하지 않습니다. 그러나 이는 객체 배열에만 적용됩니다. json 내의 모든 키를 재귀적으로 변경하는 방법을 찾고 싶습니다. 다음과 같은 JSON이 있다고 가정해 보겠습니다.

{
  "name1": "one",
  "type": "FeatureCollection",
  "features": [
    {
      "name1": "one",
      "valueA": "0",
      "valueB": "0",
      "keyB": "2",
      "keyC": "3"
    },
    {
      "name1": "two",
      "valueA": "11",
      "valueB": "21",
      "keyB": "15",
      "keyC": "20"
    }
  ]
}

내 마지막 jq명령은 이 JSON에서 작동하지 않습니다. name1재귀를 사용하여 모든 키를 변경하는 방법이 있습니까 jq? recurse(.[]?;true)해당 명령을 사용하는 방법을 찾을 수 있을까요 ? 가능합니까?

답변1

jq 'walk(if type == "object" then with_entries( if .key == "name1" then .key = "newname1" else . end ) else . end)' file

jq이는 매뉴얼(기능을 설명하는 부분 ) 에서 거의 그대로 나온 것입니다 walk(). 이 walk()함수는 "재귀 map()"처럼 동작합니다. 우리가 주의해야 할 유일한 것은 현재 처리 중인 엔터티의 유형을 확인하는 것입니다.

를 사용하면 walk()첫 번째 방법을 적용할 수도 있습니다.

jq 'walk(if type == "object" and has("name1") then ( .newname1 = .name1 | del(.name1) ) else . end)' file

그러나 이는 키가 발견된 위치를 바꾸는 대신(중요한 경우) newname1각 객체의 끝에 키를 배치 합니다.name1

또 다른 접근 방식( jq1.6)은 재귀적 괜찮은 연산자를 사용하고 .., 찾고 있는 키가 있는 객체를 선택한 다음 해당 객체를 업데이트하는 것입니다.

jq '(.. | select(has("name1")?)) |= with_entries(if .key == "name1" then .key = "newname1" else . end)' file

관련 정보