How to combine 2 JSON objects into one with jq? - json

I have two JSON objects in two files (result_0.json and result_1.json) which look like this
{
"data": {
"pools": [
{
"id": "1"
},
{
"id": "2"
}
]
}
}
and like this:
{
"data": {
"pools": [
{
"id": "3"
},
{
"id": "4"
}
]
}
}
What I would like to get looks like this:
{
"data": {
"pools": [
{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
},
{
"id": "4"
}
]
}
}
How can it be done? I tried
jq -s add result_0.json result_1.json
but it just overwrites the values in result_0.json with the values of result_1.json.

If .data and .pool are the only keys in the json files, you can use
jq -n '{ data: { pools: [inputs.data.pools] | add } }' result0 result1
This will create the desired output:
{
"data": {
"pools": [
{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
},
{
"id": "4"
}
]
}
}
Regarding the inputs keyword, consider reading JQ's docs on this part.

Related

Extract JSON including key with jq command

HERE is sample json file.
sample.json
{
"apps": [
{
"name": "app1"
},
{
"name": "app2"
},
{
"name": "app3"
}
],
"test": [
{
"name": "test1"
},
{
"name": "test2"
}
]
}
I want to divide the above JSON file into the following two files.
I want to manage the entire configuration file with one JSON, divide the file when necessary and give it to the tool.
apps.json
{
"apps": [
{
"name": "app1"
},
{
"name": "app2"
},
{
"name": "app3"
}
}
test.json
{
"test": [
{
"name": "test1"
},
{
"name": "test1"
}
]
}
jq .apps sample.json outputs only value.
[
// Not contain the key
{
"name": "app1"
},
{
"name": "app2"
},
{
"name": "app3"
}
]
Can you have any idea?
Construct a new object using {x} which is a shorthand for {x: .x}.
jq '{apps}' sample.json
{
"apps": [
{
"name": "app1"
},
{
"name": "app2"
},
{
"name": "app3"
}
]
}
Demo
And likewise with {test}.
You can do
{apps}, {test}
Demo
https://jqplay.org/s/P_9cc2uANV

Merge array by using inner property

I have different language files like these:
file1
{
"Pack": [
{
"id": "item1",
"lang": {
"en": {
}
}
},
{
"id": "item2",
"lang": {
"en": {
}
}
}
]
}
file2
{
"Pack": [
{
"id": "item1",
"lang": {
"sp": {
}
}
}
]
}
and I need to merge the same ids by lang field. Final file should looks like:
{
"Pack": [
{
"id": "item1",
"lang": {
"en": {
},
"sp": {
}
}
},
{
"id": "item2",
"lang": {
"en": {
}
}
}
]
}
I think I should use something like more complex command but my starting point is:
jq -s '{ attributes: map(.attributes[0]) }' file*.json
First you'll want to read in all files as input, then combine all Pack items and aggregating them into groups by id, then take those groups and arrange them to the result you need.
$ jq -n '
{Pack: ([inputs.Pack[]] | group_by(.id) | map({id: .[0].id, lang: (map(.lang) | add)}))}
' file*.json
This results in:
{
"Pack": [
{
"id": "item1",
"lang": {
"en": {},
"sp": {}
}
},
{
"id": "item2",
"lang": {
"en": {}
}
}
]
}

Getting unique values from nested Array using jq

Trying to get unique values stored in items array for each group. somehow it's always mixed...
My JSON looks like this:
{
"start": 1534425916,
"stop": 1535030716,
"groups": [
{
"group": "transmission",
"data": {
"events": 665762,
},
"items": [
{
"item": "manualni",
"data": {
"events": 389158,
}
},
{
"item": "automaticka",
"data": {
"events": 276604,
}
}
]
},
{
"group": "vat",
"data": {
"events": 671924,
},
"items": [
{
"item": "ne",
"data": {
"events": 346221,
}
},
{
"item": "ano",
"data": {
"events": 325703,
}
}
]
}
]
}
Desired result is the following:
{
"id": "transmission",
"value": [
"manualni",
"automaticka",
]
}
{
"id": "vat",
"value": [
"ne",
"ano"
]
}
Tried with this filter on command line:
| jq '{id: .groups[].group, value: [.groups[].items[].item]}'
Which results in the above mentioned mixed up result:
{
"id": "transmission",
"value": [
"manualni",
"automaticka",
"ne",
"ano"
]
}
{
"id": "vat",
"value": [
"manualni",
"automaticka",
"ne",
"ano"
]
}
Any idea how to receive the uniquified values here? Thanks in advance!
This gets the desired result. I think the manual entry under .[] explains why it works.
jq '.groups[] | {"id": .group, "value": [.items[].item]}'

Add to existing json file using jq

I have an Artifactory AQL Spec file in JSON format. The spec file is as follows:
{
"files": [
{
"aql": {
"items.find": {
"repo": "release-repo",
"modified": { "$before": "30d" },
"type": { "$eq": "folder" },
"depth": "2"
}
}
}
]
}
let's say I run a gitlab api query to acquire a list of SHAs that I want to iterate through and add to this json spec file.. The list of SHAs are assigned to a variable..
"a991fef6bb9e9759d513fd4b277fe3674b44e4f4"
"5a562d34bb1d4ab4264acc2c61327651218524ad"
"d4e296c35644743e58aed35d1afb87e34d6c8823"
I would like to iterate through all these commit IDs in and add them one by one to the json so that they are in this format:
{
"files": [
{
"aql": {
"items.find": {
"repo": "release-repo",
"modified": { "$before": "30d" },
"type": { "$eq": "folder" },
"$or": [
{
"$and": [
{
"name": {
"$nmatch": "*a991fef6bb9e9759d513fd4b277fe3674b44e4f4*"
}
}
]
},
{
"$and": [
{
"name": {
"$nmatch": "*5a562d34bb1d4ab4264acc2c61327651218524ad*"
}
}
]
},
{
"$and": [
{
"name": {
"$nmatch": "*d4e296c35644743e58aed35d1afb87e34d6c8823*"
}
}
]
}
],
"depth": "2"
}
}
}
]
}
The list of SHAs returned from the gitlab api query will be different everything and that's why I'd like this to be a dynamic entry or update every time. The number of returned SHAs will also be different... Could return 10 one day or it could return 50 on another day.
#!/usr/bin/env bash
template='{
"files": [
{
"aql": {
"items.find": {
"repo": "release-repo",
"modified": { "$before": "30d" },
"type": { "$eq": "folder" },
"$or": [],
"depth": "2"
}
}
}
]
}'
shas=(
"a991fef6bb9e9759d513fd4b277fe3674b44e4f4"
"5a562d34bb1d4ab4264acc2c61327651218524ad"
"d4e296c35644743e58aed35d1afb87e34d6c8823"
)
jq -n \
--argjson template "$template" \
--arg shas_str "${shas[*]}" \
'
reduce ($shas_str | split(" ") | .[]) as $sha ($template;
.files[0].aql["items.find"]["$or"] += [{
"$and": [{"name": {"$nmatch": ("*" + $sha + "*")}}]
}]
)
'
...emits as output:
{
"files": [
{
"aql": {
"items.find": {
"repo": "release-repo",
"modified": {
"$before": "30d"
},
"type": {
"$eq": "folder"
},
"$or": [
{
"$and": [
{
"name": {
"$nmatch": "*a991fef6bb9e9759d513fd4b277fe3674b44e4f4*"
}
}
]
},
{
"$and": [
{
"name": {
"$nmatch": "*5a562d34bb1d4ab4264acc2c61327651218524ad*"
}
}
]
},
{
"$and": [
{
"name": {
"$nmatch": "*d4e296c35644743e58aed35d1afb87e34d6c8823*"
}
}
]
}
],
"depth": "2"
}
}
}
]
}
Here is a reduce-free solution. It makes some inessential assumptions -
that the sha strings are presented as a stream of strings on STDIN, and that the Artifactory spec is in a file named spec.json. Here is the jq program:
map( {"$and": [ {name: { "$nmatch": "*\(.)*" }}]} ) as $x
| $spec[0] | (.files[0].aql."items.find"."$or" = $x)
The jq invocation might look like this:
jq -s --slurpfile spec spec.json -f program.jq <<< "${shas[*]}"

adding parent element to json objects using jq/bash

I want to add a parent to each of the json objects within a file.
My starting point is the following json file containing two json items:
{
"id": {
"S": "cf7ebec368f241ead7ecf818ce9ed098406afa63"
},
"test": {
"N": "5"
},
"added": {
"S": "2017-02-15T17:56:19.958917+00:00"
},
"foo": {
"N": "88"
},
"web": {
"N": "103"
}
}
{
"id": {
"S": "cf7ebec368f241ead7ecf818ce9ed098406afa63"
},
"image_server_id": {
"N": "5"
},
"added": {
"S": "2017-02-15T17:56:19.958917+00:00"
},
"result": {
"N": "88"
},
"data": {
"foo": {
"N": "103",
"S": "test"
}
}
}
Using jq and/or bash I want to generate the following json file:
{
"*StaticString*": [
{
"PutRequest": {
"Item": {
"id": {
"S": "cf7ebec368f241ead7ecf818ce9ed098406afa63"
},
"test": {
"N": "5"
},
"added": {
"S": "2017-02-15T17:56:19.958917+00:00"
},
"foo": {
"N": "88"
},
"web": {
"N": "103"
}
**}
}
},
{
"PutRequest": {
"Item": {
"id": {
"S": "cf7ebec368f241ead7ecf818ce9ed098406afa63"
},
"image_server_id": {
"N": "5"
},
"added": {
"S": "2017-02-15T17:56:19.958917+00:00"
},
"result": {
"N": "88"
},
"data": {
"foo": {
"N": "103",
"S": "test"
}
}
**}
}
}
]
}
To sum up I want to add
{
"StaticString": [
{
at the beginning of the file.
Then I need to put each json item into a parent
"PutRequest": {
"Item": {
...
}
}
and generate an array out of the json items.
I'm already knowing how to generate an array of the json items using
jq -s . testfile.json
But I don't know how to add a parent to each json item.
I hope it's clear what I want to achieve.
Thank's for your help,
Chris
Try
jq -s '{staticstring:[{PutRequest:{Item:.[]}}]}' inputfile.json