Add a single object to an array - jq

So I have this json structure:
{
"dog": [
{
"name": "sam",
"age": "2"
},
{
"name": "billy",
"age": "5"
}
]
}
I've found that .dog[1] will return me the first object but not in the dog:[] array.
{
"name": "billy",
"age": "5"
}
and .[] |= .[$i] gives me an object:
{
"dog": {
"name": "billy",
"age": "5"
}
}
What I want is:
{
"dog": [
{
"name": "sam",
"age": "2"
}
]
}
I plan to use this in a bash script, and write out to multiple files like:
jq -r --argjson i "$i" '.[] |= .[$i]' "$1"

Instead of an integer index, use a slice. (Also, the array is 0-indexed, not 1-indexed.)
$ jq --argjson i 0 '{dog: .dog[$i:$i+1]}' < tmp.json
{
"dog": [
{
"name": "sam",
"age": "2"
}
]
}
As you are asking for an object, not a string, the -r option doesn't do anything.

Try
jq --argjson i 2 '.dog|=[.[$i-1]]'
The .dog|=[.[$index]] part modifies just the array dog and replaces it with an array of just the item at position $index. This has the benefit of preserving anything else that might be in the top-level object. We use $i-1 since you indicate you want to provide 1-based indices as input.

JSON arrays starts from zero. you should use index 0 instead of 1:
.dog[0]

Related

How to get value pairs of the objects from JSON using jq

I have a json file named as param.json that looks as below:
[
{
"Value": "anshuman.ceg+Dev#gmail.com",
"Key": "AccountEmail"
},
{
"Value": "DevABC",
"Key": "AccountName"
},
{
"Value": "Security (ou-nzx5-8ajd1561)",
"Key": "ManagedOrganizationalUnit"
},
{
"Value": "anshuman.ceg+Dev#gmail.com",
"Key": "SSOUserEmail"
},
{
"Value": "John",
"Key": "SSOUserFirstName"
},
{
"Value": "Smith",
"Key": "SSOUserLastName"
}
]
I want to get only the Value for DevABC so that I can use while reading the -r line. I need only DevABC
I am using jq as follows which doesn't seem to work
jq -r .[1].Value param.json
Assuming all your Key values are distinct, you can first convert the array into an object and then access the "AccountName" property directly:
jq -r 'from_entries | .AccountName' param.json
from_entries will generate the following object, which allows you to easily access the value for a given key:
{
"AccountEmail": "anshuman.ceg+Dev#gmail.com",
"AccountName": "DevABC",
"ManagedOrganizationalUnit": "Security (ou-nzx5-8ajd1561)",
"SSOUserEmail": "anshuman.ceg+Dev#gmail.com",
"SSOUserFirstName": "John",
"SSOUserLastName": "Smith"
}
If the object keys in the input happen not to be "Key" and "Value" and you can't use from_entries, select would be a good approach:
jq --arg k 'AccountName' -r '.[] | select(.Key == $k).Value'

How to output the whole json after making change by jq

I have json file test.json:
{
"data": [
{
"id": 0,
"content": "apple"
},
{
"id": 100,
"content": "pears"
}
]
}
I want to change "content" of "id"==100 to "watermelon" then output the whole of test.json.
But when I do:
$ jq '.data[]|select(.id==100)|.content|="watermelon"' test.json
{
"id": 100,
"content": "watermelon"
}
I don't get the output of the changed whole test.json but just the portion of it.
How do I make the aforementioned change to test.json and output the whole of test.json?
I was able to fix this by:
$ jq '(.data[]|select(.id==100)).content|="watermelon"' test.json
{
"data": [
{
"id": 0,
"content": "apple"
},
{
"id": 100,
"content": "watermelon"
}
]
}
A less elegant attempt
jq '.data |= map(.content = if .id == 100 then "watermelons" else .content end)' file.json

Using jq to get arrays where a key within the array is equal to a specific value?

I have been practicing with jq play to try to get all the arrays in a list where website is == "google" and create another json list from that.
https://jqplay.org/s/DKNC2mhOLq
jq: error (at :18): Cannot index array with string "website"
exit status 5
{
"items": [
{
"name":"name1",
"id":"1",
"website":"google"
},
{
"name":"name1",
"id":"1",
"website":"google"
},
{
"name":"name1",
"id":"2",
"website":"jingle"
}
]
Desired output:
[
{
"name":"name1",
"id":"1",
"website":"google"
},
{
"name":"name1",
"id":"1",
"website":"google"
}
]
how can I loop through arrays in a list and look for specific values for specific keys? Thanks for any help or ideas you can provide. I am a begginer with JSON and jq.
Enclose the select with a map, as you want to apply the filter to each array item individually while retaining the surrounding array structure.
jq '.items | map(select(.website == "google"))'
[
{
"name": "name1",
"id": "1",
"website": "google"
},
{
"name": "name1",
"id": "1",
"website": "google"
}
]
Demo

jq: filter array and project other field

Here my document:
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": [
{
"system": {
"value": "urn:oid:1.3.6.1.4.1.19126.3"
},
"value": {
"value": "Y3454867M"
}
},
{
"system": {
"value": "urn:oid:2.16.724.4.9.10.2"
},
"value": {
"value": "108505134"
}
}
]
}
]
I need to pick only .identifier[where .system.value == "urn:oid:1.3.6.1.4.1.19126.3"] and project .identifier.value.value.
Desired output:
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": "Y3454867M"
}
]
I've been playing with map and select but I don't quite figure out what's the right way to get it.
Any ideas?
This approach uses first to get the first result, in case there is more than one array item matching the criteria.
jq --arg v "urn:oid:1.3.6.1.4.1.19126.3" '
map(.identifier |= first(.[] | select(.system.value == $v).value.value))
'
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": "Y3454867M"
}
]
Demo
Right on the money with the good ol' select tool, since you need data from an arbitrary index. I fumbled a bit before I unwrapped the inner array that gets piped to my select.
jq -r '.[] | [{id: .id, identifier: .identifier | .[] | select(.system.value | contains("urn:oid:1.3.6.1.4.1.19126.3")) | .value.value }]'
Still new to jq myself, so any feedback is welcome.

How do I use a value as a key reference in jq?

I have two JSON files as follows.
One contains a mapping of project to owners.
owners.json
{
"Project1": "owner1",
"Project2": "owner2"
}
The second contains a list of projects with extra information:
projects.json
[
{
"name": "Project1",
"base": "A"
},
{
"name": "Project2",
"base": "B"
}
]
I'd like to use JQ to merge the two files to look like the following:
output.json
[
{
"name": "Project1",
"owner": "owner1",
"base": "A"
},
{
"name": "Project2",
"owner": "owner2",
"base": "B"
}
]
My first thought was to try something like this (assuming projects.json is fed on stdin):
jq --slurpFile owners owners.json '.name as $n | [.[] | {name, base, owner: $owners[0].$n}]'
This gives a syntax error relating to the $n in $owners[0].$n. What's the right way to do this in JQ?
Thanks!
You need to wrap variable references in square brackets for indexing objects with them. Even though you corrected that your script wouldn't work as arrays can't be indexed with strings (.name as $n part).
And don't bother with slurpfile, there are simpler ways.
$ jq 'input as $owners | map(.owner = $owners[.name])' projects.json owners.json
[
{
"name": "Project1",
"base": "A",
"owner": "owner1"
},
{
"name": "Project2",
"base": "B",
"owner": "owner2"
}
]

Resources