Używam JQ narzędzi (JQ-json-Processor) w skrypcie powłoki do analizowania JSON.
Mam 2 pliki json i chcę je połączyć w jeden unikalny plik
Tutaj zawartość plików:
plik1
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2"
},
"bbb": {
"value1": "v1",
"value2": "v2"
},
"ccc": {
"value1": "v1",
"value2": "v2"
}
}
}
plik2
{
"status": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value3": "v3",
"value4": 4
},
"bbb": {
"value3": "v3"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
Spodziewany wynik
{
"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
}
}
}
Próbuję wielu kombinacji, ale jedyny wynik, jaki otrzymuję, jest następujący, co nie jest oczekiwanym wynikiem:
{
"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"
}
}
Za pomocą tego polecenia:
jq -s '.[].value' file1 file2
json
shell
command-line
jq
Janfy
źródło
źródło
json
użyj:cat f1 f2 | json --deep-merge
json
@ xer0x?json
narzędzie, wejdź na github.com/trentm/jsonOdpowiedzi:
Od wersji 1.4 jest to teraz możliwe dzięki
*
operatorowi. Gdy otrzyma dwa obiekty, połączy je rekurencyjnie. Na przykład,Ważne: Zwróć uwagę na
-s (--slurp)
flagę, która umieszcza pliki w tej samej tablicy.Dałoby ci:
Jeśli chcesz również pozbyć się innych kluczy (takich jak oczekiwany wynik), możesz to zrobić w następujący sposób:
Lub prawdopodobnie nieco bardziej wydajne (ponieważ nie łączy żadnych innych wartości):
źródło
-s
flaga jest ważna, ponieważ bez niej dwa obiekty nie znajdują się w tablicy.Zastosowanie
jq -s add
:To czyta wszystkie teksty JSON ze standardowego wejścia do tablicy (
jq -s
robi to), a następnie „redukuje” je.(
add
jest zdefiniowany jakodef add: reduce .[] as $x (null; . + $x);
, który iteruje po wartościach tablicy wejściowej / obiektu i dodaje je. Dodawanie obiektu == scal).źródło
reduce .[] as $x ({}; . * $x)
- zobacz także odpowiedź jrib .Kto wie, czy nadal go potrzebujesz, ale oto rozwiązanie.
Gdy już znajdziesz się w tej
--slurp
opcji, jest to łatwe!Wtedy
+
operator zrobi, co chcesz:(Uwaga: jeśli chcesz scalić wewnętrzne obiekty zamiast po prostu nadpisywać lewe pliki prawymi, musisz to zrobić ręcznie)
źródło
Oto wersja, która działa rekurencyjnie (używając
*
) na dowolnej liczbie obiektów:źródło
jq -s 'reduce .[] as $item ({}; . * $item)' *.json
Po pierwsze, {"wartość": .value} można skrócić do po prostu {wartość}.
Po drugie, opcja --argfile (dostępna w jq 1.4 i jq 1.5) może być interesująca, ponieważ pozwala uniknąć konieczności używania opcji --slurp.
Składając je razem, dwa obiekty w dwóch plikach można połączyć w określony sposób w następujący sposób:
Flaga '-n' mówi jq, aby nie czytał ze standardowego wejścia, ponieważ dane wejściowe pochodzą z opcji --argfile tutaj.
źródło
--argile
dla--slurpfile
Można to wykorzystać do scalenia dowolnej liczby plików określonych w poleceniu:
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
lub to dla dowolnej liczby plików
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json
źródło