jq를 사용하여 2개의 파일에서 2개의 JSON 개체를 병합하려면 어떻게 해야 합니까?
셸 스크립트의 jq 툴(jq-json-processor)을 사용하여 json을 해석하고 있습니다.
2개의 json 파일을 가지고 있으며 하나의 고유한 파일로 병합하고 싶다.
파일 내용은 다음과 같습니다.
파일 1
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2"
},
"bbb": {
"value1": "v1",
"value2": "v2"
},
"ccc": {
"value1": "v1",
"value2": "v2"
}
}
}
파일 2
{
"status": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value3": "v3",
"value4": 4
},
"bbb": {
"value3": "v3"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
기대한 결과
{
"value": {
"aaa": {
"value1": "v1",
"value2": "v2",
"value3": "v3",
"value4": 4
},
"bbb": {
"value1": "v1",
"value2": "v2",
"value3": "v3"
},
"ccc": {
"value1": "v1",
"value2": "v2"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
여러 가지 조합을 시도하지만 결과는 다음과 같습니다.이것은 기대했던 결과가 아닙니다.
{
"ccc": {
"value2": "v2",
"value1": "v1"
},
"bbb": {
"value2": "v2",
"value1": "v1"
},
"aaa": {
"value2": "v2",
"value1": "v1"
}
}
{
"ddd": {
"value4": 4,
"value3": "v3"
},
"bbb": {
"value3": "v3"
},
"aaa": {
"value4": 4,
"value3": "v3"
}
}
다음 명령어 사용:
jq -s '.[].value' file1 file2
1.4 이후부터, 이것은,*
교환입니다.2개의 오브젝트가 지정되면 재귀적으로 결합됩니다.예를들면,
jq -s '.[0] * .[1]' file1 file2
중요:주의:-s (--slurp)
flag: 파일을 같은 배열에 저장합니다.
다음과 같은 이점을 얻을 수 있습니다.
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2",
"value3": "v3",
"value4": 4
},
"bbb": {
"value1": "v1",
"value2": "v2",
"value3": "v3"
},
"ccc": {
"value1": "v1",
"value2": "v2"
},
"ddd": {
"value3": "v3",
"value4": 4
}
},
"status": 200
}
(예상했던 결과와 같이) 다른 키도 삭제하는 경우는, 다음의 방법으로 실행할 수 있습니다.
jq -s '.[0] * .[1] | {value: .value}' file1 file2
또는 (다른 값을 Marge하지 않기 때문에) 다소 더 효율적일 수 있습니다.
jq -s '.[0].value * .[1].value | {value: .}' file1 file2
사용하다jq -s add
:
$ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add
{
"a": 0,
"b": "bar",
"c": "baz"
}
그러면 stdin에서 배열로 모든 JSON 텍스트가 읽힙니다(jq -s
그렇게 되면, 「어쩔 수 없다」라고 하는 것입니다.
(add
로 정의됩니다.def add: reduce .[] as $x (null; . + $x);
입력 배열/개체 값을 반복하여 추가합니다.개체 추가 == 병합).
다음은 재귀적으로 작동하는 버전입니다(사용 방법:*
임의의 개수의 오브젝트에 대해서:
echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' |\
jq --slurp 'reduce .[] as $item ({}; . * $item)'
{
"A": {
"a": 1,
"b": 2
},
"B": 3
}
아직 필요할지 누가 알겠습니까? 하지만 여기 해결책이 있습니다.
그 다음에--slurp
옵션은 간단합니다!
--slurp/-s:
Instead of running the filter for each JSON object in the input,
read the entire input stream into a large array and run the filter just once.
그 다음에+
operator는, 다음의 조작을 실시합니다.
jq -s '.[0] + .[1]' config.json config-user.json
(주의: 왼쪽 파일 개체를 오른쪽 파일 개체와 덮어쓰기만 하는 것이 아니라 내부 개체를 병합하려면 수동으로 해야 합니다.
지금까지의 솔루션이나 코멘트는 없습니다.input
를 클릭하여 두 번째 파일에 액세스합니다.이를 채택하면 all-embracking 어레이와 같이 추출할 수 있는 추가 구조의 구축이 불필요해집니다.--slurp
(또는-s
) 옵션. 이 옵션은 다른 거의 모든 접근법에 적용됩니다.
2개의 파일을 최상위 레벨로 Marge 하려면 , 다음의 파일을 추가합니다.input
의 선두에.
사용.+
:
jq '. + input' file1.json file2.json
모든 수준에서 두 파일을 재귀적으로 병합하려면 다음을 사용하여 동일한 작업을 수행합니다.*
대신 연산자로:
jq '. * input' file1.json file2.json
즉, 두 개의 파일을 재귀적으로 병합하고 두 개의 오브젝트를 하나로 축소합니다.value
필드, 먼저 필터링을 사용하여{value}
:
jq '{value} * (input | {value})' file1.json file2.json
{
"value": {
"aaa": {
"value1": "v1",
"value2": "v2",
"value3": "v3",
"value4": 4
},
"bbb": {
"value1": "v1",
"value2": "v2",
"value3": "v3"
},
"ccc": {
"value1": "v1",
"value2": "v2"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
통합 후에만 감소하는 솔루션은 다음과 같습니다.. * input | {value}
코드는 짧아지지만, 「추출할 수 있는 추가 구조의 추가」를 다시 부활시켜, 최종적으로 부품이 커지면 대량의 오버헤드가 발생할 가능성이 있습니다.
하려면 , 2개의 파일 중 어느쪽인가를 합니다.input
번,으로 모든 것을 합니다.inputs
''와 같이''는
jq 'reduce inputs as $i (.; . * $i)' file*.json
첫 은 항상 컨텍스트를 ..
동시에input(s)
나머지 파일만 처리합니다(즉, 두 번째 파일부터 시작).--null-input
★★★★★★★★★★★★★★★★★」-n
옵션이 주어집니다).
이 명령어는 명령어로 지정된 파일 수에 관계없이 병합할 수 있습니다.
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
또는 임의의 개수의 파일에 대해
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json
먼저 {"value": .value}는 단순히 {value}로 축약할 수 있습니다.
둘째, --argfile 옵션(jq 1.4 및 jq 1.5에서 사용 가능)은 --slurp 옵션을 사용할 필요가 없기 때문에 관심을 가질 수 있습니다.
이것들을 조합하면, 2개의 파일내의 2개의 오브젝트를 다음과 같이 지정된 방법으로 조합할 수 있습니다.
$ jq -n --argfile o1 file1 --argfile o2 file2 '$o1 * $o2 | {value}'
'-n' 플래그는 입력이 --argfile 옵션에서 나오기 때문에 stdin에서 읽지 않도록 jq를 지시합니다.
--argfile에 대한 주의사항
에서는 jq를 사용하지 않습니다.--argfile
그 의미는 중요하지 않기 때문에 지정된 입력 파일에 정확히1개의 JSON 엔티티가 포함되어 있는 경우 해당 엔티티는 그대로 읽힙니다.그렇지 않은 경우 스트림 내의 항목은 배열로 래핑됩니다.
사용하는 몇 볼 수 .--argfile을 사용하는 것이 .그 때, 다음의 점에 주의해 주세요.--slurpfile
비효율을 초래하지 않습니다.-s
명령줄 옵션을 선택합니다.
개체에서 고유하지 않은 이전 키를 삭제하지 않으려는 경우
jq -n '{a:1, c:2}, {b:3, d:4}, {a:5,d:6}' |
jq -s 'map(to_entries)|flatten|group_by(.key)|map({(.[0].key):map(.value)|add})|add'
{
"a": 6,
"b": 3,
"c": 2,
"d": 10
}
값 값 후합니다.map(.value)|̶a̶d̶d̶
jq -n '{a:1, c:2}, {b:3, d:4}, {a:5,d:6}' |
jq -s 'map(to_entries)|flatten|group_by(.key)|map({(.[0].key):map(.value)})|add'
{
"a": [1, 5],
"b": [3],
"c": [2],
"d": [4, 6]
}
명령어의 각 부분을 제거하고 각 단계에서 개체 배열이 어떻게 변경되는지 확인하십시오.aka는 다음 단계를 실행하여 출력의 변화를 확인합니다.
map(to_entries)
map(to_entries)|flatten
map(to_entries)|flatten|group_by(.key)
map(to_entries)|flatten|group_by(.key)|map({(.[0].key):map(.value)})
map(to_entries)|flatten|group_by(.key)|map({(.[0].key):map(.value)})|add
언급URL : https://stackoverflow.com/questions/19529688/how-to-merge-2-json-objects-from-2-files-using-jq
'prosource' 카테고리의 다른 글
공허한 약속을 angularjs로 작성하시겠습니까? (0) | 2023.03.14 |
---|---|
Ajax를 사용하여 데이터 테이블에서 모든 행을 내보내려면 어떻게 해야 합니까? (0) | 2023.03.14 |
Angular의 ng-src에 대한 이미지 로드 이벤트JS (0) | 2023.03.14 |
Polylang에서 언어 전환기를 드롭다운으로 표시하는 방법 (0) | 2023.03.14 |
FormData 중첩된 개체 추가 (0) | 2023.03.14 |