Add json object into another json object using bash/jq - json

I am trying to create a new file adding the object defined in country1.json into world.json. Essentially:
world.json
{
"class": "world",
"version": "1.1.0"
}
+
country1.json
{
"class": "country",
"country_1": {
"class": "city",
"name": "seattle"
}
}
=
world_country1.json
{
"class": "world",
"version": "1.1.0",
"country1": {
"class": "country",
"country_1": {
"class": "city",
"name": "seattle"
}
}
}
Using the filename for the objects in country1.json file. I would like to use bash/jq if possible.
Thanks for your help,
Best,
Romain

Use input to access the second file, and redirect using > into another file
jq '.country1 = input' world.json country1.json > world_country1.json
{
"class": "world",
"version": "1.1.0",
"country1": {
"class": "country",
"country_1": {
"class": "city",
"name": "seattle"
}
}
}
Demo
If you want to utilize the file's name for the new field's name, use input_filename and cut off the last 5 characters (removing .json):
jq '. + (input | {(input_filename[:-5]): .})' world.json country1.json > world_country1.json

Related

jq map object fields from TeemIP IPAM databese to fields for Kea DHCP server

How to transform data about PCs from TeemIP IPAM database, to feed it to Kea DHCP server as reservations with jq.
This is the data I would like to transform
{
"objects": {
"PC::8": {
"code": 0,
"message": "",
"class": "PC",
"key": "8",
"fields": {
"name": "ntb",
"macaddress": "50:74:9d:b5:5f:5d",
"ipaddress_id_friendlyname": "10.1.1.6"
}
},
"PC::7": {
"code": 0,
"message": "",
"class": "PC",
"key": "7",
"fields": {
"name": "pc",
"macaddress": "00:11:c0:92:ab:0e",
"ipaddress_id_friendlyname": "10.1.70.70"
}
}
},
"code": 0,
"message": "Found: 2"
}
to this output
{
"hostname": "ntb",
"hw-address": "50:74:9d:b5:5f:5d",
"ip-address": "10.1.1.6"
},
{
"hostname": "pc",
"hw-address": "00:11:c0:92:ab:0e",
"ip-address": "10.1.70.70"
}
I've tried something like
cat pcs.json |jq '[.[]]|.[]|.[]|.[]|.[]|map(.)|{hostname: .name, hw-address: .macaddress, ip-address: .ipaddress_id_friendlyname}'
But I was not successful by any means. I'm total noob with json. Please help.
Navigate to and iterate over the target items using .objects[].fields, and construct your objects:
jq '
.objects[].fields | {
hostname: .name,
"hw-address": .macaddress,
"ip-address": .ipaddress_id_friendlyname
}
'
{
"hostname": "ntb",
"hw-address": "50:74:9d:b5:5f:5d",
"ip-address": "10.1.1.6"
}
{
"hostname": "pc",
"hw-address": "00:11:c0:92:ab:0e",
"ip-address": "10.1.70.70"
}
Demo
This produces a so-called stream of objects (no commas in between). If you rather wanted an array of objects (enclosed in square brackets, and its items delimited by commas), just surround the whole filter with a pair of brackets.

Create new JSON value out of strings extracted from another

I have a json file with the following input
{
"Arg":"room=Rhasspy rhasspyName",
"Results": [
{
"Name":"TV",
"Internals": { },
"Readings": { },
"Attributes": { "rhasspyName": "TV" }
},
{
"Name":"dyTest01",
"Internals": { },
"Readings": { },
"Attributes": { "rhasspyName": "radio" }
},
{
"Name":"enoAcPC01",
"Internals": { },
"Readings": { },
"Attributes": { "rhasspyName": "pc" }
} ],
"totalResultsReturned":3
}
With jq '.Results | .[] | .["Attributes"] | .rhasspyName' -r I can get a list like
TV
radio
pc
How can I take this input and create a new json looking like
{"Devices":["TV","radio","pc"]}
Put them into an array and pair that with Devices key in an object.
$ jq '{Devices:[.Results[].Attributes.rhasspyName]}' file
{
"Devices": [
"TV",
"radio",
"pc"
]
}
To create a new file with that JSON value, redirect JQ's stdout to a file, like:
jq '{Devices:[.Results[].Attributes.rhasspyName]}' file > newfile

Python accessing element inside array inside json

Can someone help me to access myapp from below json using python, please ?
{
"Data": {
"Name": "myname",
"AccountName": "test",
"classic": [
{
"cName": "mycname",
"tags": ["tag1", "tag2"],
"Version": "1.14.10",
"app": "myapp"
}
]
}
}
Use json.load for reading a file or json.loads for a string.
data_dict = json.loads(your_data)
print(data_dict["Data"]["classic"][0]["app"])
Use json loads to parse a json string and json dumps for stringifying the json to a json string
Here in your case you will need json loads
input = {
"Data": {
"Name": "myname",
"AccountName": "test",
"classic": [
{
"cName": "mycname",
"tags": ["tag1", "tag2"],
"Version": "1.14.10",
"app": "myapp"
}
]
}
}
parsed_input = json.loads(input)
output = parsed_input["Data"]["classic"][0]["app"]
print(output)
You can use json library for the same.
input_json= {
"Data": {
"Name": "myname",
"AccountName": "test",
"classic": [
{
"cName": "mycname",
"tags": ["tag1", "tag2"],
"Version": "1.14.10",
"app": "myapp"
}
]
}
}
data = json.loads(input_json)
result=data["Data"]["classic"][0]["app"])

Parse JSON array with HTML tags to output plain HTML

I've been Googling for this for last 2 days.
I couldn't get it done perfectly.
I assume, this belongs or can be done by some template engines, but.. I was not able to find that so-called engine.
I have this JSON array and I'd like to parse it back or convert it to plain HTML to output it to the browser.
[
{
"tag": "figure",
"children": [
{
"tag": "div",
"attrs": {
"class": "fiwrapper"
},
"children": [
{
"tag": "img",
"attrs": {
"src": "/media/images/5cbd41bd7c566057f5e6a875.jpeg"
}
}
]
},
{
"tag": "figcaption",
"children": [
""
]
}
]
},
{
"tag": "p",
"children": [
{
"tag": "br"
}
]
},
{
"tag": "figure",
"children": [
{
"tag": "div",
"attrs": {
"class": "fiwrapper"
},
"children": [
{
"tag": "img",
"attrs": {
"src": "/media/images/5cbd45286c7210581c5563ba.jpeg"
}
}
]
},
{
"tag": "figcaption",
"children": [
""
]
}
]
},
{
"tag": "p",
"children": [
{
"tag": "br"
}
]
},
{
"tag": "p",
"children": [
"Cool Stuff.."
]
}
]
Help is more than appreciated..
All you need to do this is a recursive parser that will parse the json from top to bottom.
here is the parser to do so in javascript and the same logic can be translated into any other language as well.
const getAttrMap = (attr) => attr ? Object.keys(attr).reduce((acc, curr) => `${acc} ${curr}="${attr[curr]}"`, '') : '';
function parseArr(arr) {
return arr.map(curr => parser(curr)).join('\n');
}
function parser(obj) {
if (typeof obj === 'object') {
if (!obj.children) {
return `<${obj.tag} ${getAttrMap(obj.attrs)}/>`
}
return `<${obj.tag} ${getAttrMap(obj.attrs)}>${
obj.children instanceof Array ? parseArr(obj.children) : parser(obj.children)}</${obj.tag}>`;
}
if (!obj) {
return '';
}
return obj;
}
// usage
parseArr(inputJson);
Explanation
If we know how to translate one block we can translate each block recursively.
To parse one block the logic is simple.
<${obj.tag} ${getAttrMap(obj.attrs)}>CHILD</${obj.tag}>
This will convert an object into an HTML tag but what if CHILD is another tag itself?
simple we call the same parser function again, however in this case CHILD can be an array (multiple tags) or a single one based of that we either call parseArr or parser. In cases where children are not provided, we simply return the empty string.
Output
<figure ><div class="fiwrapper"><img src="/media/images/5cbd41bd7c566057f5e6a875.jpeg"></img></div>
<figcaption ></figcaption></figure>
<p ><br ></br></p>
<figure ><div class="fiwrapper"><img src="/media/images/5cbd45286c7210581c5563ba.jpeg"></img></div>
<figcaption ></figcaption></figure>
<p ><br ></p>
<p >Cool Stuff..</p>``

Proper Mapping for dynamic fields

I have the following document structure:
{
"some_field": "some_data",
"entries": {
{"id": "some_id", "type": "some_type", "value": "some_value"},
{"id": "another_id", "type": "another_type", "value": {"foo": 1, "bar": "two"}
}
}
So I would like to map entries based on the "type" field.
Which maping type or flag should I use?
Or maybe I need to change my doc structure?
Could you use this one
{
"some_field":"some_data",
"entries":[{
"id":"some_id",
"type":"some_type",
"value":"some_value"
},
{
"id":"another_id",
"type":"another_type",
"value":{
"foo":1,
"bar":"two"
}
}]
}