how to select element or delete output string - jq

I have a json contents
"objects" : [ {
"uid" : "2272dba0-9ffb-49d4-88b7-0a18f38a3cdc",
"name" : "All_Internet",
},
{
"uid" : "b83fd31c-3cb3-406e-b46b-816a138e8ea1",
"name" : "Public FTP",
} ]
I used :
jq '.objects[] | .name
and got the resule:
"All_Internet"
"Public FTP"
how to select the secondary "name" string, or removing the first "name" "All_Internet" of output
the "All_Internet" is fixed string.
Regards and thanks

It's unclear whether you want an answer like #KiranKandel's, namely:
.objects[].name | select(. != "All_Internet")
or something like:
.objects[1:][].name

Related

Adding key name to value using jq

I am trying to dynamically assign the key name as its value in my json
This is the json i am using:
{
"test1": "",
"test2": "",
"test3": ""
}
the result i would like to obtain looks like this:
{
"test1": "test1",
"test2": "test2",
"test3": "test3"
}
I am not familiar with jq and the closest result i got is using:
keys[] as $key | {"\($key)": "\($key)"} | .
here is the output:
{
"test1": "test1"
}
{
"test2": "test2"
}
{
"test3": "test3"
}
with_entries lets you manipulate .key and .value for each field. Just set one to the value of the other:
with_entries(.value = .key)
{
"test1": "test1",
"test2": "test2",
"test3": "test3"
}
Demo
Following your approach, you could collect your result objects into an array using the array constructors […] around your filter, and then add up the array's items producing one merged object. (Note that | . can be dropped as it doesn't do anything but reproduce itself, and that the string interpolation "\($key)" is just the same as $key, given $key is a string, which is the case here as object field names are always strings.)
[keys[] as $key | {($key): $key}] | add
Demo
You may also entirely drop the use of variables as there is no other context interfering:
[keys[] | {"\(.)": .}] | add
Demo
And there is a shortcut for patterns like [.[] | …] called map:
keys | map({"\(.)": .}) | add
Demo
Alternatively, you also might want to consider using reduce for an iterative manipulation, and/or keys_unsorted which acts like keys but produces the keys in the original (unsorted) order:
reduce keys_unsorted[] as $key (.; .[$key] = $key)
Demo

Terraform: Add item to a DynamoDB Table

What is the correct way to add tuple and key-pair values items to a DynamoDB database via Terraform?
I am trying like this:
resource "aws_dynamodb_table_item" "item" {
table_name = aws_dynamodb_table.dynamodb-table.name
hash_key = aws_dynamodb_table.dynamodb-table.hash_key
for_each = {
"0" = {
location = "Madrid"
coordinates = [["lat", "40.49"], ["lng", "-3.56"]]
visible = false
destinations = [0, 4]
}
}
item = <<ITEM
{
"id": { "N": "${each.key}"},
"location": {"S" : "${each.value.location}"},
"visible": {"B" : "${each.value.visible}"},
"destinations": {"L" : [{"N": "${each.value.destinations}"}]
}
ITEM
}
And I am getting the message:
each.value.destinations is tuple with 2 elements
│
│ Cannot include the given value in a string template: string required.
I also have no clue on how to add the coordinates variable.
Thanks!
List should be something like that :
"destinations": {"L": [{ "N" : 1 }, { "N" : 2 }]}
You are trying to pass
"destinations": {"L": [{ "N" : [0,4] }]}
Also you are missing the last } in destinations key
TLDR: I think the problem here is that you are trying to put L(N) - i.e. a list of numeric values, while your current Terraform code tries to put all the destinations into one N/number.
Instead of:
[{"N": "${each.value.destinations}"}]
you need some iteration over destinations and building a {"N": ...} of them.
"destinations": {"NS": ${jsonencode(each.value.destinations)}}
Did the trick!

How to know if there are other paths than a given path?

Is it possible to know with JSONPath that other "paths" exist?
By an existing "path" I mean a string in the form "a.b.c" or "a.b.d" like for this JSON:
{
'a' : {
'b' : [ { 'c' : 0 }, { 'd': 1 ]
}
}
Can a JSONPath be written to tell if there any other "paths" other then a.b.c and a.b.d ?
For example in the following JSON, it should find that there is the property 'e':
{
'a' : {
'b' : [ { 'c' : 0 }, { 'd': 1 ],
'e': 2
}
}
It depends on JSONPath Implementation. The jsonpath options have a setting to output the path or value.
JSONPATH
$..*
All possible Output Paths
[
"$['a']",
"$['a']['b']",
"$['a']['e']",
"$['a']['b'][0]",
"$['a']['b'][1]",
"$['a']['b'][0]['c']",
"$['a']['b'][1]['d']"
]
Tool : https://jsonpath.com/
Checkbox Option : Output paths
Tool : https://jsonpath.herokuapp.com/
Checkbox option : Normalized path expressions

Add values to a JSON array if outer array's name == 'something'

I'm passing a JSON object to jq and want to add extra objects to an inner array ('accessories') if its parent array ('platforms') matches a certain name.
Here's my source JSON:
{
"bridge": {
"name": "Homebridge",
"port": 51395
},
"accessories": [],
"platforms": [
{
"name": "Config",
"port": 8581,
"platform": "config"
},
{
"platform": "homebridge-cbus.CBus",
"name": "CBus",
"client_ip_address": "127.0.0.1",
"accessories": [
{
"values": "existing"
}
]
}
]
}
This works beautifully:
jq '.platforms[1].accessories += [{ "values" : "NEW" }]'
... but of course it's poor form to expect platforms[1] to always the be array I want to append to, so I set about trying to form the right syntax for a search or if/then/else to only act on the .name of the appropriate one.
I thought this was my solution:
jq '.platforms[] | if ( .name=="CBus" ) then .accessories += [{ "values" : "NEW" }] else . end'
... until I realised it was only passing the 'platforms' through and eating the 'bridge' object and empty outer 'accessories' array, which I need to retain.
My issue looks to be similar to JQ | Updating array element selected by `select`, but I've tried LOTS of combinations but just can't break through.
Edit: Here's the correct JQPlay I've been working with:
https://jqplay.org/s/dGDswqAEte
Thanks for any help.
That's a good attempt. The key here is to use the select() function to identify the object you are going to update and overwrite the overall array using |= operator, i.e.
.platforms |= ( map(select(.name == "CBus").accessories += [{ "values" : "NEW" }] ) )
For the snippet in your jq-play link (now removed), you need to do
.gcp_price_list."CP-COMPUTEENGINE-OS"
|= with_entries(select(.value.cores == "shared").value.cores = "0.5")
Or if you want to be even more specific, and keep the entry in gcp_price_list configurable, do
.gcp_price_list |=
with_entries (
select(.key == "CP-COMPUTEENGINE-OS").value |=
with_entries(
select(.value.cores == "shared").value.cores = "0.5") )

ElasticSearch - Range filter by date is not working,

I'm trying to filter a query using range by date but it's not working. If i use gt, gte, lt, lte it returns zero results. If i use only gt or lt, it returns some results but the filter is not working.
I've checked datatype on uri http://mydomain.local:9200/logstash-2014.09.09/_mapping?pretty=true the field type is correct:
"original" : {
"type" : "date",
"format" : "dateOptionalTime"
}
Here is an example of a result that i have indexed in ElasticSearch:
{
"_index" : "logstash-2014.09.08",
"_type" : "iis",
"_id" : "wxtnfpyjR4u7dhwlEAWevw",
"_score" : 1.0,
"_source":{"#version":"1","#timestamp":"2014-09-08T20:55:46.460Z",
"type":"iis","original":"14-09-08 17:39:58"}
}
And here is how i'm trying to perform a query:
{
"query" : {
"filtered" : {
"filter" : {
"range" : {
"original" : {
"gt" : "14-09-10"
}
}
}
}
}
}
Anyone knows what is wrong on my query? Why it returns some results if i don't have any date greater than today ( 2014-09-09 )?
I created an index with the same mapping and tried to put a record in
curl -XPOST localhost:9200/test-1/x/_index -d '{"original": "14-09-08 17:39:58"}'
and got an error:
{"error":"MapperParsingException[failed to parse [original]]; nested: MapperParsingException[failed to parse date field [14-09-08 17:39:58], tried both date format [dateOptionalTime], and timestamp number with locale []]; nested: IllegalArgumentException[Invalid format: \"14-09-08 17:39:58\" is malformed at \" 17:39:58\"]; ","status":400}`
So I believe that you are in a a locale where that ##-##-## is being interpreted as something other than yy-mm-dd.
You are using Logstash so you can fix the original field before it goes in with a mutate to make it unambiguous.
mutate {
replace => { original => "20%{original}" }
}

Resources