jq update substring matched object - string

Json file:
{
"A": "jack",
"B": [
{
"name": "jack/jil",
"version": "0.1"
},
{
"name": "went/well",
"version": "1.2"
}
]
}
now I need to update every objects version: "$version-dev" where name starts from jack while retaining rest of the json intact.
the closest I can get.
jq '.B[] | select(.name|test("jack.")) | .version += "-dev"' old.json > new.json
in the above command I'm only getting the that particular object with updated value in the new.json but I need the whole json too.
any suggestions

You need to put parantheses around the whole selection to be updated: (… | .version) += …
jq '(.B[] | select(.name|test("jack.")) | .version) += "-dev"' old.json > new.json
{
"A": "jack",
"B": [
{
"name": "jack/jil",
"version": "0.1-dev"
},
{
"name": "went/well",
"version": "1.2"
}
]
}
Demo

Related

Azure Devops : Replace variable in list with unknown order

We are running a build pipeline in azure DevOps. After the build we deploy the stuff and substitute variables in JSON files.
I have a problem substituting a variable in a list of equal objects. My son looks like this:
"Friends": [
{ "Name": "John",
"Phone": "12345678"
},
{ "Name": "Frank",
"Phone": "12235578"
},
{ "Name": "Bill",
"Phone": "13790678"
}
]
I can substitute Franks phone using the path: Friends.1.Phone
What should I do, if the order of "Friends" is not determined and I can not use the index?
I searched for the azure plugin "variable substitution condition" but I couldn't find any useful task.
You can use a powershell task and use Convertfrom-Json command
$Json = #'
{
"Friends": [
{ "Name": "John",
"Phone": "12345678"
},
{ "Name": "Frank",
"Phone": "12235578"
},
{ "Name": "Bill",
"Phone": "13790678"
}
]
}
'#
$result = $Json | ConvertFrom-Json
$result.Friends[0].Phone='12345'
$result | ConvertTo-Json -Depth 4
This will change 'John' phone number.
Answer 2:
$result = $Json | ConvertFrom-Json
$result.Friends | % {if($_.name -eq 'john'){$_.phone=98765}}
$result | ConvertTo-Json -depth 10

How to extract selected key and value from nested dictionary object in a list?

I have a list example_list contains two dict objects, it looks like this:
[
{
"Meta": {
"ID": "1234567",
"XXX": "XXX"
},
"bbb": {
"ccc": {
"ddd": {
"eee": {
"fff": {
"xxxxxx": "xxxxx"
},
"www": [
{
"categories": {
"ppp": [
{
"content": {
"name": "apple",
"price": "0.111"
},
"xxx: "xxx"
}
]
},
"date": "A2020-01-01"
}
]
}
}
}
}
},
{
"Meta": {
"ID": "78945612",
"XXX": "XXX"
},
"bbb": {
"ccc": {
"ddd": {
"eee": {
"fff": {
"xxxxxx": "xxxxx"
},
"www": [
{
"categories": {
"ppp": [
{
"content": {
"name": "banana",
"price": "12.599"
},
"xxx: "xxx"
}
]
},
"date": "A2020-01-01"
}
]
}
}
}
}
}
]
now I want to filter the items and only keep "ID": "xxx" and the correspoding value for "price": "0.111", expected result can be something similar to :
[{"ID": "1234567", "price": "0.111"}, {"ID": "78945612", "price": "12.599"}]
or something like {"1234567":"0.111", "78945612":"12.599" }
Here's what I've tried:
map_list=[]
map_dict={}
for item in example_list:
#get 'ID' for each item in 'meta'
map_dict['ID'] = item['meta']['ID']
# get 'price'
data_list = item['bbb']['ccc']['ddd']['www']
for data in data_list:
for dataitem in data['categories']['ppp']
map_dict['price'] = item["content"]["price"]
map_list.append(map_dict)
print(map_list)
The result for this doesn't look right, feels like the item isn't iterating properly, it gives me result:
[{"ID": "78945612", "price": "12.599"}, {"ID": "78945612", "price": "12.599"}]
It gave me duplicated result for the second ID but where is the first ID?
Can someone take a look for me please, thanks.
Update:
From some comments from another question, I understand the reason for the output keeps been overwritten is because the key name in the dict is always the same, but I'm not sure how to fix this because the key and value needs to be extracted from different level of for loops, any help would be appreciated, thanks.
as #Scott Hunter has mentioned, you need to create a new map_dict everytime you are trying to do this. Here is a quick fix to your solution (I am sadly not able to test it right now, but it seems right to me).
map_list=[]
for item in example_list:
# get 'price'
data_list = item['bbb']['ccc']['ddd']['www']
for data in data_list:
for dataitem in data['categories']['ppp']:
map_dict={}
map_dict['ID'] = item['meta']['ID']
map_dict['price'] = item["content"]["price"]
map_list.append(map_dict)
print(map_list)
But what are you doing here is that you are basically just "forcing" your way through ... I recommend you to take a break and check out somekind of tutorial, which will help you to understand how it really works in the back-end. This is how I would have written it:
list_dicts = []
for example in example_list:
for www in item['bbb']['ccc']['ddd']['www']:
for www_item in www:
list_dicts.append({
'ID': item['meta']['ID'],
'price': www_item["content"]["price"]
})
Good luck with this problem and hope it helps :)
You need to create a new dictionary for map_dict for each ID.

BASH How to treat JSON inside a variable to remove only a specific part of the text

I have a big JSON inside a var and I need to remove only from that specific comma ( and I have incontable number of others comma before that ) until the penultimate Curly Brackets..
in short, Only the BOLD text..... ( text between ** and next ** )
edit
originally there is no ** in json, I put it in the code just to show where it starts and ends what I want to remove
##################################################
}
]
}**,
"meta": {
"timeout": 0,
"priority": "LOW_PRIORITY",
"validationType": "SAME_FINGERS",
"labelFilters": [],
"externalIDs": [
{
"name": "chaveProcesso",
"key": "01025.2021.0002170"
}
]
}**
}
It would help if you showed more context, but basically you want something like:
jq 'del(.meta)'
or:
jq 'with_entries(select(.key != "meta"))'
eg:
#!/bin/sh
json='{
"foo": 5,
"meta": {
"timeout": 0,
"priority": "LOW_PRIORITY",
"validationType": "SAME_FINGERS",
"labelFilters": [],
"externalIDs": [
{
"name": "chaveProcesso",
"key": "01025.2021.0002170"
}
]
}
}'
echo "$json" | jq 'del(.meta)'

Replacing a value for a given key in Kusto

I am trying to use the .set-or-replace command to amend the "subject" entry below from sample/consumption/backups to sample/consumption/backup but I am not having much look in the world of Kusto.
I can't seem to reference the sub headings within Records, data.
"source_": CustomEventRawRecords,
"Records": [
{
"metadataVersion": "1",
"dataVersion": "",
"eventType": "consumptionRecorded",
"eventTime": "1970-01-01T00:00:00.0000000Z",
"subject": "sample/consumption/backups",
"topic": "/subscriptions/1234567890id/resourceGroups/rg/providers/Microsoft.EventGrid/topics/webhook",
"data": {
"resourceId": "/subscriptions/1234567890id/resourceGroups/RG/providers/Microsoft.Compute/virtualMachines/vm"
},
"id": "1234567890id"
}
],
Command I've tried to get to work;
.set-or-replace [async] CustomEventRawRecords [with (subject = sample/consumption/backup [, ...])] <| QueryOrCommand
If you're already manipulating the data, why not turn it into a columnar representation? that way you can easily make the corrections you want to make and also get the full richness of the tabular operators plus an intellisense experience that will help you formulate queries easily
here's an example query that will do that:
execute query in browser
datatable (x: dynamic)[dynamic({"source_": "CustomEventRawRecords",
"Records": [
{
"metadataVersion": "1",
"dataVersion": "",
"eventType": "consumptionRecorded",
"eventTime": "1970-01-01T00:00:00.0000000Z",
"subject": "sample/consumption/backups",
"topic": "/subscriptions/1234567890id/resourceGroups/rg/providers/Microsoft.EventGrid/topics/webhook",
"data": {
"resourceId": "/subscriptions/1234567890id/resourceGroups/RG/providers/Microsoft.Compute/virtualMachines/vm"
},
"id": "1234567890id"
}
]})]
| extend records = x.Records
| mv-expand record=records
| extend subject = tostring(record.subject)
| extend subject = iff(subject == "sample/consumption/backups", "sample/consumption/backup", subject)
| extend metadataVersion = tostring(record.metadataVersion)
| extend dataVersion = tostring(record.dataVersion)
| extend eventType = tostring(record.eventType)
| extend topic= tostring(record.topic)
| extend data = record.data
| extend id = tostring(record.id)
| project-away x, records, record

jq parsing and linux formatting to desired output

I am trying to format json output and exclude an element when a condition is met.
1) In this case I'd like to exclude any element that contains "valueFrom" using jq
[{
"name": "var1",
"value": "var1value"
},
{
"name": "var2",
"value": "var2value"
},
{
"name": "var3",
"value": "var3value"
},
{
"name": "var4",
"value": "var4value"
},
{ # <<< exclude this element as valueFrom exists
"name": "var5",
"valueFrom": {
"secretKeyRef": {
"key": "var5",
"name": "var5value"
}
}
}
]
After excluding the element mentioned above I am trying to return a result set that looks like this.
var1: var1value
var2: var2value
var3: var3value
var4: var4value
Any feedback is appreciated. Thanks.
Select array items that doesn't have the valueFrom key using a combination of select/1, has/1, and not/0. Then format the objects as you please.
$ jq -r '.[] | select(has("valueFrom") | not) | "\(.name): \(.value)"' input.json

Resources