extract values from JSON using jq - json

I have a JSON object that looks like this:
{
"Accounts": [
{
"Id": "1",
"Name": "Joe",
"Zip": "11111"
},
{
"Id": "2",
"Name": "Jack",
"Zip": "22222"
}
]
}
I am trying to write a jq query that gives me this:
[
{
"Id": "1",
"Name": "Joe"
},
{
"Id": "2",
"Name": "Jack"
}
]
How can I do that? Thanks.

jq '.Accounts | map({ Id, Name })'
Will produce
[
{
"Id": "1",
"Name": "Joe"
},
{
"Id": "2",
"Name": "Jack"
}
]
as you can try online using this demo.
.Accounts selects the Accounts key
map() will apply the following for each object [docs]
Create object with Id and Name key [docs]

Demo https://jqplay.org/s/v01P2gDVc8
You can do
[.Accounts[] | {Id, Name}]

Related

How do I use jq to flatten a complex json structure?

I have the following simplified json structure: Notice an array of values, which have children, whose children could have children.
{
"value": [
{
"id": "12",
"text": "Beverages",
"state": "closed",
"attributes": null,
"iconCls": null
},
{
"id": "10",
"text": "Foods",
"state": "closed",
"attributes": null,
"iconCls": null,
"children": [
{
"id": "33",
"text": "Mexican",
"state": "closed",
"attributes": null,
"iconCls": null,
"children": [
{
"id": "6100",
"text": "Taco",
"count": "3",
"attributes": null,
"iconCls": ""
}
]
}
]
}
]
}
How do I flatten a json structure using jq? I would like to print each element just once, but in a flat structure. An example output:
{
"id": "12",
"category": "Beverages"
},
{
"id": "10",
"category": "Foods"
},
{
"id": "33",
"category": "Mexican"
},
{
"id": "6100",
"category": "Tacos"
}
My attempt doesn't seem to work at all:
cat simple.json - | jq '.value[] | {id: .id, category: .text} + {id: .children[]?.id, category: .children[]?.text}'
.. is your friend:
.. | objects | select( .id and .text) | {id, category: .text}
If your actual input is that simple, recursively extracting id and text from each object under value should work.
[ .value | recurse | objects | {id, category: .text} ]
Online demo
I was totally going in the wrong direction
Not really. Going in that direction, you would have something like:
.value[]
| recurse(.children[]?)
| {id, category: .text}

Re-organize json using jq

I want to re-organize a json using jq.
My json is like:
[
{
"id": "id1",
"name": "Robin"
},
{
"id": "id2",
"name": "John"
},
{
"id": "id3",
"name": "Jane"
}
]
I want to have an output as :
[
{
"Robin": "id1"
},
{
"John": "id2"
},
{
"Jane": "id3"
}
]
How to achieve this?
Thanks in advance
Yu need:
cat data1.jtxt | jq 'to_entries|map({(.value.name):(.value.id)})'
My output:
[
{
"Robin": "id1"
},
{
"John": "id2"
},
{
"Jane": "id3"
}
]
I cannot understand how was this command so difficult to find
[.[] | {(.id):.name}] | add
gives you:
{
"id1": "Robin",
"id2": "John",
"id3": "Jane"
}
If you want to keep the "object separation" just remove the | add
This question somehow led me to it.

Using jq to convert object to key with values

I have been playing around with jq to format a json file but I am having some issues trying to solve a particular transformation. Given a test.json file in this format:
[
{
"name": "A", // This would be the first key
"number": 1,
"type": "apple",
"city": "NYC" // This would be the second key
},
{
"name": "A",
"number": "5",
"type": "apple",
"city": "LA"
},
{
"name": "A",
"number": 2,
"type": "apple",
"city": "NYC"
},
{
"name": "B",
"number": 3,
"type": "apple",
"city": "NYC"
}
]
I was wondering, how can I format it this way using jq?
[
{
"key": "A",
"values": [
{
"key": "NYC",
"values": [
{
"number": 1,
"type": "a"
},
{
"number": 2,
"type": "b"
}
]
},
{
"key": "LA",
"values": [
{
"number": 5,
"type": "b"
}
]
}
]
},
{
"key": "B",
"values": [
{
"key": "NYC",
"values": [
{
"number": 3,
"type": "apple"
}
]
}
]
}
]
I have followed this thread Using jq, convert array of name/value pairs to object with named keys and tried to group the json using this expression
jq '. | group_by(.name) | group_by(.city) ' ./test.json
but I have not been able to add the keys in the output.
You'll want to group the items at the different levels and building out your result objects as you want.
group_by(.name) | map({
key: .[0].name,
values: (group_by(.city) | map({
key: .[0].city,
values: map({number,type})
}))
})
Just keep in mind that group_by/1 yields groups in a sorted order. You'll probably want an implementation that preserves that order.
def group_by_unsorted(key_selector):
reduce .[] as $i ({};
.["\($i|key_selector)"] += [$i]
)|[.[]];

Using jq to return specific information in JSON object

I wish to parse individual elements of inner JSON object to build / load in the database.
The following is the JSON object. How can I parse elements like id, name queue etc? I will iterate it in loop and work and build the insert query.
{
"apps": {
"app": [
{
"id": "application_1540378900448_18838",
"user": "hive",
"name": "insert overwrite tabl...summary_view_stg_etl(Stage-2)",
"queue": "Data_Ingestion",
"state": "FINISHED",
"finalStatus": "SUCCEEDED",
"progress": 100
},
{
"id": "application_1540378900448_18833",
"user": "hive",
"name": "insert into SNOW_WORK...metric_definitions')(Stage-13)",
"queue": "Data_Ingestion",
"state": "FINISHED",
"finalStatus": "SUCCEEDED",
"progress": 100
}
]
}
}
You're better off converting the data to a format easily consumed by a database processor, like csv, then do something about it.
$ jq -r '(.apps.app[0] | keys_unsorted) as $k
| $k, (.apps.app[] | [.[$k[]]])
| #csv
' input.json
its pretty simple just fetch elment which is having an array of values.
var JSONOBJ={
"apps": {
"app": [
{
"id": "application_1540378900448_18838",
"user": "hive",
"name": "insert overwrite tabl...summary_view_stg_etl(Stage-2)",
"queue": "Data_Ingestion",
"state": "FINISHED",
"finalStatus": "SUCCEEDED",
"progress": 100
},
{
"id": "application_1540378900448_18833",
"user": "hive",
"name": "insert into SNOW_WORK...metric_definitions')(Stage-13)",
"queue": "Data_Ingestion",
"state": "FINISHED",
"finalStatus": "SUCCEEDED",
"progress": 100
}
]
}
}
JSONOBJ.apps.app.forEach(function(o){console.log(o.id);console.log(o.user);console.log(o.name);})

jq add capturing group result outside

For example,
Input:
{
"id":"abc",
"name": "name-middlenane-lastname-1"
},
{
"id":"123",
"name": "fname-flast-2"
}
response:
{
"id":"abc",
"name": "name-middlename-lastname-1",
"newkey": "name-middlename-lastname"
},
{
"id":"123",
"name": "fname-flast-2",
"newkey": "fname-flast"
}
The filed name in each object is a string with characters and numbers separated by "-" hyphen. I need the complete string from beginning till the starting number. I don't want anything which is there after the number. And then the add new field with key as newkey and value should be extracted string without the number. Thus, the output should contain old fields as well as new one.
jq solution:
Sample input.json:
[
{
"id": "abc",
"name": "name-middlenane-lastname-1"
},
{
"id": "123",
"name": "fname-flast-2"
}
]
jq 'map(. + (.name | capture("(?<newkey>.+)-[0-9]+")) )' input.json
The output:
[
{
"id": "abc",
"name": "name-middlenane-lastname-1",
"newkey": "name-middlenane-lastname"
},
{
"id": "123",
"name": "fname-flast-2",
"newkey": "fname-flast"
}
]