다음 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
또 다른 접근 방식( jq
1.6)은 재귀적 괜찮은 연산자를 사용하고 ..
, 찾고 있는 키가 있는 객체를 선택한 다음 해당 객체를 업데이트하는 것입니다.
jq '(.. | select(has("name1")?)) |= with_entries(if .key == "name1" then .key = "newname1" else . end)' file