using jq how to query and replace value within an array - arrays

How do I query and replace the value for SMT_PORT_3306_TCP_ADDR.
I tried
echo $task_definition | jq -r '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="SMT_PORT_3306_TCP_ADDR")| .value = "myvalue" '
the output I get
{
"name": "SMT_PORT_3306_TCP_ADDR",
"value": "myvalue"
}
I do not get the full json
Input Json :
{
"taskDefinition": {
"taskDefinitionArn": "some value",
"containerDefinitions": [
{
"name": "common-api-img",
"environment": [
{
"name": "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
"value": "false"
},
{
"name": "SMT_PORT_3306_TCP_ADDR",
"value": "valueToReplace"
}
],
"mountPoints": [],
"volumesFrom": []
}
],
"revision": 65,
"volumes": [],
"status": "ACTIVE"
}
}
Expected output without the top level taskDefinition value:
{
"taskDefinitionArn":"some value",
"containerDefinitions":[
{
"name":"common-api-img",
"environment":[
{
"name":"SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
"value":"false"
},
{
"name":"SMT_PORT_3306_TCP_ADDR",
"value":"myvalue"
}
],
"mountPoints":[
],
"volumesFrom":[
]
}
],
"revision":65,
"volumes":[
],
"status":"ACTIVE"
}

Use |= with if.
jq '.taskDefinition.containerDefinitions[0].environment[]
|= if .name == "SMT_PORT_3306_TCP_ADDR"
then .value = "myvalue"
else .
end'

Related

How to filter JSON data based on another JSON data in typescript

I have 2 JSON Data 1. Payers 2. Rules. I need to filter Payers JSON data based on PayerId from Rules JSON data.
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}}
Rules JSON file
{
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
}]}
I need to filter Payers JSON data based on Rules JSON data if PayerID matches
I need output like below
{
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "34567",
"name": "Test Payer3"
}
}
How to filter?
You can use Array.filter like that (based on your data structure):
const filteredPayers = payersObj.Payers.filter((p) => rulesObj.Rules[0].Criteria[0].payerId.includes(p.payerId));
I can't figure out why your Rules json looks like this, I guess you have multiple rules. If so, you will need to iterate over each rule and invoke includes. Same for Criteria.
Code will check each rule and each critirias
and will return payers if payerId found in any of the given rules of any criteria
const payers = {
"Payers": [
{
"payerId": "12345",
"name": "Test Payer1"
},
{
"payerId": "23456",
"name": "Test Payer2",
},
{
"payerId": "34567",
"name": "Test Payer3"
}]}
const rules = {
"Rules": [
{
"actions": {
"canCopyRule": true
},
"RuleId": 123,
"description": "Test Rule",
"isDisabled": false,
"Criteria": [
{
"autoSecondaryCriteriaId": 8888,
"criteriaType": { "code": "primaryPayer", "value": "Primary Payer" },
"payerId": ["12345", "34567"]
}
]
}
]
}
const data = payers.Payers.filter(payer => rules.Rules.findIndex(rule => rule.Criteria.findIndex(criteria => criteria.payerId.includes(payer.payerId)) != -1) !== -1)
console.log(data)

Loop on JSON array in bash script and pull data through JQ

i want to pull data from jSON file through jq in bash script. I have 50 plus SG objects in JSON .
here is an example of one SG . I want to print a VPC id and group id in one line and so on for another objects.
Solution i tried :
jq -c . $old |
while IFS= read -r obj; do
vpcidold=$( printf '%s' "$obj" | jq '.SecurityGroups[].VpcId')
securityidold=$( printf '%s' "$obj" | jq '.SecurityGroups[].GroupId')
echo "${vpcidold}||${securityidold}"
done > oldtest.json
it is working file but giving data in a line by line and want to do more optimised this with for loop.
How can I create a loop on JSON array to get desire output
"SG": [
{
"Description": "des",
"GroupName": "Gpname",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"ToPort": 80,
"UserIdGroupPairs": []
}
],
"OwnerId": "123",
"GroupId": "sg",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"Tags": [
{
"Key": "projectcode",
"Value": "none"
},
{
"Key": "sgid",
"Value": "sg-123"
}
],
"VpcId": "vpc-123"
}
]
},
If the JSON file is just an array of the objects, you don't need to loop over them in bash. jq will loop over them implicitely:
jq -r '.[][][] | (.VpcId + "||" + .GroupId)' file.json
Tested on the following input:
[
{ "SG": [
{
"Description": "des",
"GroupName": "Gpname",
"GroupId": "sg",
"VpcId": "vpc-123"
}
] },
{ "SG": [
{
"Description": "des",
"GroupName": "xyz",
"GroupId": "sg-12345",
"VpcId": "vpc-12345"
}
] }
]
Output:
vpc-123||sg
vpc-12345||sg-12345

Using jq to convert list of map into an array

I am struggling to get formatted output from an aws dynamodb scan command.
An item in the dynamodb table looks like below:
{
"labels": {
"Category": [
"Data",
"EMR"
],
"Environment": "NonProd",
"Severity": "Critical"
},
"subscriber_id": "blah#blah.com",
"subscriber_type": "email"
}
When I run the query:
aws dynamodb scan --table-name dummy_table --region region_name --
profile default --query "Items[?subscriber_id.S ==
'blah#blah.com'].labels.M[]"
I get the output as below:
[
{
"Environment": {
"S": "NonProd"
},
"Severity": {
"S": "Critical"
},
"Category": {
"L": [
{
"S": "Data"
},
{
"S": "EMR"
}
]
}
}
]
Desired output is:
{
"Category": [
"Data",
"EMR"
],
"Environment": "NonProd",
"Severity": "Critical"
}
To achieve the desired output, I tried to manipulate using jq.
Updated query:
aws dynamodb scan --table-name dummy_table --region
region_name --
profile default --query "Items[?subscriber_id.S ==
'blah#blah.com'].labels.M[]" |
jq -r '.[]
| to_entries[]
| [{key:.key, value:.value[]}]
| from_entries' | jq -s add
Output is:
{
"Environment": "NonProd",
"Severity": "Critical",
"Category": [
{
"S": "Data"
},
{
"S": "EMR"
}
]
}
As you see it's close, but it's not processing the Category list. Any help with getting the desired output is appreciated.
Thanks
You can use the following :
.[] | { Environment: .Environment.S, Severity: .Severity.S, Category: (.Category.L | map(.S)) }
Output :
{
"Environment": "NonProd",
"Severity": "Critical",
"Category": [
"Data",
"EMR"
]
}
Try it here !

Parsing JSON with Powershell's ConvertFrom-Json

I am trying to parse this JSON using Powershell's ConvertFrom-Json feature, but it seems to truncate the data:
{
"MessagesMonitoring": {
"version": 1,
"description": "Message Description"
},
"data": {
"swindon": {
"totalMessages": 0,
"identifier": [
{
"name": "ET",
"staleCount": 4
},
{
"name": "ET_2",
"staleCount": 4
}
]
},
"Reading": {
"totalMessages": 0,
"identifier": [
{
"name": "J3",
"staleCount": 2
}
]
},
"Yanki": {
"totalMessages": 0,
"identifier": [
{
"name": "UT",
"staleCount": 4
},
{
"name": "UT_2",
"staleCount": 4
}
]
}
}
}
Request:
$request = 'http://localhost:8000/hi.json'
Invoke-WebRequest $request |
ConvertFrom-Json |
Select swindon
Response:
StatusCode : 200 StatusDescription : OK
Content : {
"MessagesMonitoring": {
"version": 1,
"description": "Message Description"
},
"data": {
"swindon": {
"totalMessages": 0,
"identifier": [
{
"na...
Not sure what I may be doing incorrectly. Any advise/guidance on how to parse the JSON into this format would be great.
swindon|identifier|ET|4
swindon|totalMessages|0
swindon|identifier|ET2|4
Reading|identifier|J3|2
Reading|totalMessages|0
Yanki|identifier|UT|4
Yanki|identifier|U_T|4
Yanki|totalMessages|0
You are missing a step. The Content element of the response contains the JSON, so that's what you need to feed into ConvertFrom-Json:
$request = 'http://localhost:8000/hi.json'
$resp = $(Invoke-WebRequest $request).Content | ConvertFrom-Json
Then, within the JSON you have a dictionary, within which the "data" key contains the information I think you're interested in, access it using this syntax:
$resp.data
That should get you started

How to use jolt to parse array of array

I want to use jolt to parse the json. But I can't get the age value in the first level successfully. May someone help me?
The input json is like this:
{
"name": "abc",
"age": "20",
"Photos": [
{
"a": "AAA.jpg",
"b": "BBB.jpg",
"XXX123": [
{
"v1": "AAA.jpg",
"v2": "BBB.jpg"
}
]
}
]
}
My Spec:
[
{
"operation": "shift",
"spec": {
"Photos": {
"*": {
"XXX123": {
"*": {
//"*": "&2.[&1].&",
"#(2,a)": "&2.[&1].a",
"#(2,b)": "&2.[&1].b",
"#(3,age)": "&3.[&1].age"
}
}
}
}
}
}
]
The output I want:
{
"XXX123" : [ {
"a" : "AAA.jpg",
"b" : "BBB.jpg",
"age" : "20"
} ]
}
Spec
[
{
"operation": "shift",
"spec": {
"Photos": {
"*": {
"XXX123": {
"*": {
//"*": "&2.[&1].&",
"#(2,a)": "&2.[&1].a",
"#(2,b)": "&2.[&1].b",
"#(4,age)": "&2.[&1].age"
}
}
}
}
}
}
]
You were close.
"#(3,age)": "&3.[&1].age"
needed
"#(4,age)": "&2.[&1].age"
From where that line was you needed to go up the tree 5 levels.
Counting from Zero
0 -> "*"
1 -> "XXX123"
2 -> "*"
3 -> "Photos"
4 -> your top level input
then lookup "age" in the top level map

Resources