Я использую инструменты jq (jq-json-processor) в сценарии оболочки для анализа json.
У меня есть 2 файла json и я хочу объединить их в один уникальный файл
Вот содержимое файлов:
file1
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2"
},
"bbb": {
"value1": "v1",
"value2": "v2"
},
"ccc": {
"value1": "v1",
"value2": "v2"
}
}
}
file2
{
"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
json
shell
command-line
jq
Janfy
источник
источник
json
используйте:cat f1 f2 | json --deep-merge
json
@ xer0x?json
инструмент, перейдите на github.com/trentm/jsonОтветы:
Начиная с версии 1.4 это возможно с помощью
*
оператора. Когда даны два объекта, он рекурсивно объединит их. Например,Важно: обратите внимание на
-s (--slurp)
флаг, который помещает файлы в один массив.Вы бы получили:
Если вы также хотите избавиться от других ключей (например, от ожидаемого результата), один из способов сделать это:
Или предположительно несколько более эффективный (потому что он не объединяет никакие другие значения):
источник
-s
флаг важен, поскольку без него два объекта не входят в массив.Использование
jq -s add
:Это считывает все тексты JSON из stdin в массив (
jq -s
делает это), а затем «сокращает» их.(
add
определяется какdef add: reduce .[] as $x (null; . + $x);
, который выполняет итерацию по значениям входного массива / объекта и добавляет их. Добавление объекта == слияние.)источник
reduce .[] as $x ({}; . * $x)
- см. Также ответ jrib .Кто знает, нужно ли вам это еще, но вот решение.
Как только вы дойдете до
--slurp
опции, это будет просто!Тогда
+
оператор сделает то, что вы хотите:(Примечание: если вы хотите объединить внутренние объекты вместо того, чтобы просто перезаписывать левые файловые объекты правыми, вам нужно будет сделать это вручную)
источник
Вот версия, которая рекурсивно работает (с использованием
*
) на произвольном количестве объектов:источник
jq -s 'reduce .[] as $item ({}; . * $item)' *.json
Во-первых, {"value": .value} можно сократить до {value}.
Во-вторых, опция --argfile (доступная в jq 1.4 и jq 1.5) может представлять интерес, так как позволяет избежать использования опции --slurp.
Собрав их вместе, два объекта в двух файлах можно объединить указанным ниже образом:
Флаг '-n' указывает jq не читать из stdin, поскольку здесь вводятся параметры --argfile.
источник
--argile
для--slurpfile
Это можно использовать для объединения любого количества файлов, указанных в команде:
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
или это для любого количества файлов
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json
источник