From the following input:
{
"key1": {
"key_x": "1",
...
"key_z": "2"
},
"key2": {
"key_x": "2",
...
"key_z": "3"
}
}
I would like to exclude all keys with the name "key_x" so the result should be
{
"key1": {
...
"key_z": "2"
},
"key2": {
...
"key_z": "3"
}
}
You can use the del() function:
jq 'del(.[]|.key_x)' input.json
Related
Given the following input:
{
"text": "a1\nb2"
}
How do I get the following output:
[
{
"letter": "a",
"number": 1
},
{
"letter": "b",
"number": 2
}
]
I've tried using capture with the "g" flag, but this yields two documents instead of a single document with an array of captured inputs:
$ echo '{
"text": "a1\\nb2"
}' | jq '.text | capture("(?<letter>[a-z])(?<number>[0-9])";"g")'
{
"letter": "a",
"number": "1"
}
{
"letter": "b",
"number": "2"
}
Here is a link to the jqplay example.
Why not just wrap the capture in a new array:
.text | [ capture("(?<letter>[a-z])(?<number>[0-9])";"g") ]
JqPlay
So, say I have this JSON...
[
{
"a": "1",
"blah": "true"
},
{
"b": "2",
"blah": "false"
},
{
"c": "3",
"blah": "true"
}
]
...and then use jq to select certain entries...
jq '.[] | select(.blah=="true)'
I get this...
{
"a": "1",
"blah": "true"
}
{
"c": "3",
"blah": "true"
}
But I want it to look like...
[
{
"a": "1",
"blah": "true"
}
{
"c": "3",
"blah": "true"
}
]
...this, so that I can use indexing to get certain of these entries. How do I do that?
Simply indicate you want the result in a list by wrapping the expression with [];
> cat test.json | jq '[.[] | select(.blah=="true")]'
[
{
"a": "1",
"blah": "true"
},
{
"c": "3",
"blah": "true"
}
]
Using map to iterate over the array
jq 'map(select(.blah == "true"))'
I have this json:
{
"books": [
{
"bookId": "1",
"bookName": "name1",
"bookYear": "2010"
},
{
"bookId": "2",
"bookName": "name2",
"bookYear": "2010"
}
]
}
and I want to remove the list that contains "bookId": "1"
The result should be:
{
"books": [
{
"bookId": "2",
"bookName": "name2",
"bookYear": "2010"
}
]
}
I've tried this code:
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
JsonSlurper slurper = new JsonSlurper()
String jsonString = vars.get("jsonOutput")
def parsedJson = slurper.parseText(jsonString)
log.info("Json before: " + jsonString)
int num = parsedJson.books.size()
for(int i=0;i<parsedJson.books.size();i++){
parsedJson.books[i].values().removeAll(value -> value.equals("1"))
}
def json = JsonOutput.toJson(parsedJson)
log.info("Json after: " + json.toString())
but it removes only the "bookId" from list:
Json before: {"books":[{"bookId":"1","bookName":"name1","bookYear":"2010"},{"bookId":"2","bookName":"name2","bookYear":"2010"}]}
Json after: {"books":[{"bookName":"name1","bookYear":"2010"},{"bookId":"2","bookName":"name2","bookYear":"2010"}]}
Please, could you help me on that?
You can filter the list of books like so:
def parsedJson = slurper.parseText(jsonString)
parsedJson.books = parsedJson.books.findAll { it.bookId != '1' }
def json = JsonOutput.toJson(parsedJson)
With the following inputs:
# file1.json
{
"uid": "1",
"name": "jack"
}
{
"uid": "2",
"name": "jill"
}
# file2.json
{
"fid": "a",
"file": "sample1.txt",
"uid": "1"
}
{
"fid": "b",
"file": "sample2.txt",
"uid": "1"
}
{
"fid": "c",
"file": "sample3.txt",
"uid": "2"
}
How do I go about inserting the name key-value pair to the object in the file2.json. The output I'm trying to get is as follows:
{
"fid": "a",
"file": "sample1.txt",
"uid": "1",
"name": "jack"
}
{
"fid": "b",
"file": "sample2.txt",
"uid": "1",
"name": "jack"
}
{
"fid": "c",
"file": "sample3.txt",
"uid": "2",
"name": "jill"
}
Solutions posted on merge json objects with jq and join two json files based on common key with jq utility or alternative way from command line both seems to only return the last matching pair. See below.
{"uid":"1","name":"jack","fid":"b","file":"sample2.txt"}
{"uid":"2","name":"jill","fid":"c","file":"sample3.txt"}
You will need to "slurp" file1.json, e.g. by invoking jq as follows:
jq -n -f merge.jq --slurpfile file1 file1.json file2.json
where merge.jq contains:
INDEX($file1[]; .uid) as $dict
| inputs
| . + $dict[.uid]
def INDEX
If your jq does not have INDEX/2, then simply add its def:
def INDEX(stream; idx_expr):
reduce stream as $row ({}; .[$row|idx_expr|tostring] = $row);
Want to parse the following:
{
"issues": [
{ "id": "1", "fields": { "links": [] } },
{ "id": "2", "fields": { "links": [ { "inlink": { "id": "red" } } ] } },
{ "id": "3", "fields": { "links": [ { "outlink": { "id": "yellow" } } ] } },
{ "id": "4", "fields": { "links": [ { "inlink": { "id": "green" } }, { "outlink": { "id": "blue" } } ] } }
]
}
into elements that represent the links elements, one for one, like this (note that id 1 is missing and id 4 appears twice:
{ "id": "2", "link": { "linktype": "inlink", "id": "red" } },
{ "id": "3", "link": { "linktype": "outlink", "id": "yellow" } },
{ "id": "4", "link": { "linktype": "inlink", "id": "green" } },
{ "id": "4", "link": { "linktype": "outlink", "id": "blue" } }
The following jq works for inlink or outlink separately
.issues[] | .id as $id | .fields.links[] | .inlink.id as $lid | {$id,$lid}
giving
{ "id": "2", "lid": "red" }
{ "id": "3", "lid": null }
{ "id": "4", "lid": "green" }
{ "id": "4", "lid": null }
but can't figure out how to track both types simultaneously or introduce the key linktype. Any ideas?
jq solution:
jq -c '.issues[] | .id as $id
| .fields.links[] | to_entries[]
| {"id": $id, "link": {"linktype": .key, "id": .value.id}}' file
The output:
{"id":"2","link":{"linktype":"inlink","id":"red"}}
{"id":"3","link":{"linktype":"outlink","id":"yellow"}}
{"id":"4","link":{"linktype":"inlink","id":"green"}}
{"id":"4","link":{"linktype":"outlink","id":"blue"}}