I'm trying to get this output the device name "test"
My filter is .[] | [.deviceName] and it's returning error: (at :7): Cannot index array with string "deviceName"
{
"test": [
{
"deviceName": "test",
"monitoringServer": "server1"
}
]
}
Presumably you meant:
jq '.test[] | [.deviceName]'
or perhaps:
jq '.[][] | [.deviceName]'
but without knowing your requirements, it's hard to say. That's one of the reasons why the http://stackoverflow.com/help/mcve guidelines were formulated.
Related
Can I output the ip and source id only when source id is duplicate it should out put all ip in one array if no duplicate ip can be output with corresponding source id
{"ip":"192.134.5.31","access_key":"223434354656767","source_id":"2e74a68a-2fef-443544-815d-87"}
{"ip":"172.23.54.4","saccess_key":"223434354656767","source_id":"2e74a68a-2fef-443544-815d-87"}
{"ip":"182,555,44.44","access_key":"223434354656767","source_id":"2e74a68a-2fef-443544-815d-222"}
I dont care about access key here also if this access key can be done with Jq would be great
unique_by(.ip) |{ip.source_id[]}
.ip| select(.source_id[])
You should group_by to group all the matching source_id.
Then you can create the desired output, for example:
group_by(.source_id)[] | { ip: map(.ip), source_id: (first.source_id) }
Will output:
{
"ip": [
"182,555,44.44"
],
"source_id": "2e74a68a-2fef-443544-815d-222"
}
{
"ip": [
"192.134.5.31",
"172.23.54.4"
],
"source_id": "2e74a68a-2fef-443544-815d-87"
}
Since
We group on source_id
We create an object for each group, containing
An map() from all the lower ip's and the source_id taken from the first object
Use the --slurp option to combine those objects in to an array:
jq --slurp 'group_by(.source_id)[] | { ip: map(.ip), source_id: (first.source_id) }'
JqPlay Demo
I'm not sure what your expected output is, but if you are trying to group IPs by source id like such:
{
"2e74a68a-2fef-443544-815d-222": [
"182,555,44.44"
],
"2e74a68a-2fef-443544-815d-87": [
"192.134.5.31",
"172.23.54.4"
]
}
Then you can group by your source_id and then transform the output:
group_by(.source_id) | map({(.[0].source_id): map(.ip)}) | add
Or by using a custom function:
def group(k): group_by(k) | map({key:first|k, value:.}) | from_entries;
group(.source_id) | map_values(map(.ip))
or
def group(k;v): group_by(k) | map({key:first|k, value:map(v)}) | from_entries;
group(.source_id;.ip)
I am new to jq and can't seem to quite get the syntax right for what I want to do. I am executing a command and piping its JSON output into jq. The structure looks like this:
{
"timestamp": 1658186185,
"nodes": {
"x3006c0s13b1n0": {
"Mom": "x3006c0s13b1n0.hsn.cm",
"Port": 15002,
"state": "free",
"pcpus": 64,
"resources_available": {
"arch": "linux",
"gputype": "A100",
"host": "x3006c0s13b1n0",
"mem": "527672488kb",
"ncpus": 64,
"ngpus": 4,
"system": "polaris",
"tier0": "x3006-g1",
"tier1": "g1",
"vnode": "x3006c0s13b1n0"
},
"resources_assigned": {},
"comment": "CHC- Offlined due to node health check failure",
"resv_enable": "True",
"sharing": "default_shared",
"license": "l",
"last_state_change_time": 1658175652,
"last_used_time": 1658175652
},
And so on with a record for each node. In psuedocode, what I want to do is this:
if state is not free then display nodename : {comment = "Why is the node down"}
The nodename is the key, but could be extracted from a field inside the record. However, for future reference, I would like to understand how to get the key. I figured out (I think) that you can't use == on strings, but instead have to use the regex functions.
This gives me the if state is not free part:
<stdin> | jq '.nodes[] | .state | test("free") | not'
This gives me an object with the Mom (which includes the key) and the comment:
jq '.nodes[] | {Mom: .Mom, comment: .comment}'
The question is how do I put all that together? And as for the keys, this gives me a list of the keys: jq '.nodes | keys' but that uses the non-array version of nodes.
One way without touching the keys would be to only select those array items that match the condition, and map the remaining items' value to the comment itself using map_values:
jq '.nodes | map_values(select(.state != "free").comment)'
{
"x3006c0s13b1n0": "CHC- Offlined due to node health check failure"
}
Keeping the whole comments object, which is closer to your desired output, would be similar:
jq '.nodes | map_values(select(.state != "free") | {comment})'
{
"x3006c0s13b1n0": {
"comment": "CHC- Offlined due to node health check failure"
}
}
Accessing the keys directly is still possible though. You may want to have a look at keys, keys_unsorted or to_entries.
I have limited experience with jq and am having an issue doing a a select contains for a string in a boolean. This is my json and am looking to get back just tdonn.
[
"user",
"admin"
]
[
[
"tdonn",
true
]
]
Here is what im trying. I have tried many different ways too.
jq -e -r '.results[] | .series[] | select(.values[] | contains("tdon"))[]'
With the sample JSON shown in a comment, the following filter would produce the result shown:
.results[] | .series[][] | flatten[] | select(contains("tdon")?)
Output with -r option
tdonn
You might like to consider:
jq '.. | strings | select(contains("tdon"))'
I have a json as follows:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"batchPools": {
"value": [
{
"networkConfiguration": {
"subnetId": "/subscriptions/xxxx/resourceGroups/xxx/providers/Microsoft.Network/virtualNetworks/xxxxx/subnets/sample-name-batch",
"subnetAddressPrefix": ""
}
},
{
"networkConfiguration": {
"subnetId": "/subscriptions/xxxx/resourceGroups/xxx/providers/Microsoft.Network/virtualNetworks/xxxxx/subnets/sample-name",
"subnetAddressPrefix": ""
}
}
]
}
}
}
I need to check if any of the networkConfiguration.subnetID under the array value contains the string batch. If yes then nothing needs to be done. Else, append -batch to the existing value. In this case, only the second networkConfiguration.subnetID of the array should be updated.
I tried the following:
(.parameters.batchPools.value[] | select(.networkConfiguration.subnetId | contains("-batch") | not) | .networkConfiguration.subnetId) |= (.networkConfiguration.subnetId+"-batch")
I get the following error:
jq: error (at <stdin>:38): Cannot index string with string "networkConfiguration" exit status 5
I tried this:
(.parameters.batchPools.value[] | select(.networkConfiguration.subnetId | contains("batch") | not) | .networkConfiguration.subnetId) |= "someValue"
This worked fine and replaced the entire subnetId with someValue. I am not able to figure out why the previous command is not working out. Please help.
You don't need to use the whole path of subnetId again. You've already selected that node from the pipeline before. Just use the += append operator to suffix the required string
( .parameters.batchPools.value[] |
select(.networkConfiguration.subnetId | contains("batch") | not) |
.networkConfiguration.subnetId ) += "-batch"
jqplay - Online demo
I need help in correcting jq test cases syntax. Following is output file & trying to test ID list with command below. Gives error index to string type.
[[ $(echo $output| jq -r '.output.value[] | select(.identity).id_list') == *"id2"* ]]
output = {
"resource_output": {
"value": {
"identity": [
{
"id_list": [
"/subscriptions/---/id1",
"/subscriptions/---/id2",
"/subscriptions/--/id3"
],
"principal_id": "",
"tenant_id": "",
"type": "managed"
}
]
}
}
Your query does not match the sample JSON, and you have not indicated what output you are expecting, but the following variation of your query illustrates how to use select and test with your data along the lines suggested by your attempt:
echo "$output" |
jq -r '.resource_output.identity[].id_list[] | select(test("id2"))'
Output:
/subscriptions/---/id2