get all folder-ids in my account in Nebius cloud? - jq

Using nebius-cloud-cli I am trying to list only name and id of all folders in my account.
I tried this:
yc vpc networks list --format json | jq ".[] "
The output I got was:
{
"id": "ccm979ujel7gpcq6aulc",
"folder_id": "b489aa1fe17nphuomth8",
"created_at": "2022-12-12T17:47:24Z",
"name": "default",
"description": "Auto-created network"
}
{
"id": "ccmn8qvg1uaaaiblc05e",
"folder_id": "b4aaav1fe1gnphuomth8",
"created_at": "2022-12-29T12:07:40Z",
"name": "my-network"
}
{
"id": "campid2asepq3bc68fn6",
"folder_id": "b489kv3ae1ga1huomth8",
"created_at": "2021-12-18T09:54:01Z",
"name": "my-nw",
"description": "Auto-created network"
}
Expected output:
[
{"name": "default",
"folder_id": "b4aaav1fe1gnphuomth8"
},
{"name": my-nw,
"folder_id": "b489kv3ae1ga1huomth8"
}
]
Try it out
The output I got is a multi line non standard JSON coming from this output, and needs to be handled correctly.
I'm looking for a simple transformation, not redirection and awks and stuff like this << in bash which defeats the purpose.

Use map({ name, folder_id }) with --slurp:
command | jq --slurp 'map({ name, folder_id })'
--slurp
Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.
Documentation
Input:
{
"id": "ccm979ujel7gpcq6aulc",
"folder_id": "b489aa1fe17nphuomth8",
"created_at": "2022-12-12T17:47:24Z",
"name": "default",
"description": "Auto-created network"
}
{
"id": "ccmn8qvg1uaaaiblc05e",
"folder_id": "b4aaav1fe1gnphuomth8",
"created_at": "2022-12-29T12:07:40Z",
"name": "my-network"
}
{
"id": "campid2asepq3bc68fn6",
"folder_id": "b489kv3ae1ga1huomth8",
"created_at": "2021-12-18T09:54:01Z",
"name": "my-nw",
"description": "Auto-created network"
}
Output
[
{
"name": "default",
"folder_id": "b489aa1fe17nphuomth8"
},
{
"name": "my-network",
"folder_id": "b4aaav1fe1gnphuomth8"
},
{
"name": "my-nw",
"folder_id": "b489kv3ae1ga1huomth8"
}
]
Demo
JqPlay Demo

Since you use .[] in your question, this makes me think the output of the command is an array. Use map to apply a transformation to each item in the array:
$ yc ...
[
{...},
{...}
]
$ yc ... | jq 'map({ name, folder_id })'
[
{...},
{...}
]
.[] streams all items of an array. To transform the stream, use the object construction without map:
$ yc ...
[
{...},
{...}
]
$ yc ... | jq '.[] | { name, folder_id }'
{...}
{...}
Or if yc outputs multiple JSON objects, then don't stream and transform directly:
$ yc ...
{...}
{...}
$ yc ... | jq '{ name, folder_id }'
{...}
{...}
If the output of yc is actually a single object with multiple properties, you can still use map like with a regular array; it will automatically return the properties' values only:
$ yc ...
{
"a": {...},
"b": {...}
}
$ yc ... | jq 'map({ name, folder_id })'
[
{...},
{...}
]
If yc outputs multiple JSON objects and you need the output to be an array, then slurp the input with -s/--slurp into one big array and then apply the map operation:
$ yc ...
{...}
{...}
$ yc ... | jq -s 'map({ name, folder_id })'
[
{...},
{...}
]

Assuming calling yc vpc networks list --format json just by itself produces something structured like
{
"networks": [
{
"id": "4e8a4034-a973-4f1f-84a8-73ea54adcee1",
"name": "my-network",
"description": "My network",
"created_at": "2022-01-01T00:00:00Z",
"folder_id": "b1g7f0d3-2e0a-4714-ba6a-b1g7f0d32e0a",
"vpc_id": "b1g7f0d3-2e0a-4714-ba6a-b1g7f0d32e0a",
"region_id": "ru-central1"
}
]
}
Then piping this into jq '.networks | map({name, folder_id})' would give you
[
{
"name": "my-network",
"folder_id": "b1g7f0d3-2e0a-4714-ba6a-b1g7f0d32e0a"
}
]
Demo

Related

Evaluating command inside JQ pipeline

I'm struggling evaluating a command inside a jq pipeline. Example will make it easier. Let's imagine I've got this simple json
{
"model": [{
"id": "an-id",
"path": [
"mypath1.txt"
],
"model": "foo"
},
{
"id": "an-id2",
"path": [
"mypath1.txt"
],
"model": "foo2"
}
]
}
And I want to convert into this
{
"model": [{
"id": "an-id",
"path": [
"mypath1.txt"
],
"model": "foo",
"alternative_model": "I am a computed value out of <foo>"
},
{
"id": "an-id2",
"path": [
"mypath1.txt"
],
"model": "foo2",
"alternative_model": "I am a computed value out of <foo2>"
}
]
}
I want to do something like this that allows me to delegate computing alternative model to a different bash script.
myNewJson=$(cat mappings.json | jq '[.model[]| {
id: .id,
path: .path
model: .model
alternative_model: //TODO}' ---> here I'd like to do something like "eval ./myscript $model"
])
Thanks!
Let's assume myscript contains following line :
echo "I am a computed value out of <$1>"
As jq does not allow to evaluate shell commands, you need something like :
#!/usr/bin/env bash
input=mappings.json
alternative-models(){
local result='{}' sres
for id in $(jq -r '.model[].id' $input); do
model="$(jq -r --arg id "$id" '.model[]|select(.id==$id).model' $input)"
amodel="$(./myscript $model)"
result="$(jq --arg id $id --arg amodel "$amodel" '. + { $id: $amodel }' <<< "$result")"
done
echo "$result"
}
jq --argjson amodels "$(alternative-models)" '.model|map({
id, path, model, "alternative_model": $amodels[.id] }
)' $input
Your mappings.json is not valid json because of a comma on the model line.

How to get value pairs of the objects from JSON using jq

I have a json file named as param.json that looks as below:
[
{
"Value": "anshuman.ceg+Dev#gmail.com",
"Key": "AccountEmail"
},
{
"Value": "DevABC",
"Key": "AccountName"
},
{
"Value": "Security (ou-nzx5-8ajd1561)",
"Key": "ManagedOrganizationalUnit"
},
{
"Value": "anshuman.ceg+Dev#gmail.com",
"Key": "SSOUserEmail"
},
{
"Value": "John",
"Key": "SSOUserFirstName"
},
{
"Value": "Smith",
"Key": "SSOUserLastName"
}
]
I want to get only the Value for DevABC so that I can use while reading the -r line. I need only DevABC
I am using jq as follows which doesn't seem to work
jq -r .[1].Value param.json
Assuming all your Key values are distinct, you can first convert the array into an object and then access the "AccountName" property directly:
jq -r 'from_entries | .AccountName' param.json
from_entries will generate the following object, which allows you to easily access the value for a given key:
{
"AccountEmail": "anshuman.ceg+Dev#gmail.com",
"AccountName": "DevABC",
"ManagedOrganizationalUnit": "Security (ou-nzx5-8ajd1561)",
"SSOUserEmail": "anshuman.ceg+Dev#gmail.com",
"SSOUserFirstName": "John",
"SSOUserLastName": "Smith"
}
If the object keys in the input happen not to be "Key" and "Value" and you can't use from_entries, select would be a good approach:
jq --arg k 'AccountName' -r '.[] | select(.Key == $k).Value'

jq: filter array and project other field

Here my document:
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": [
{
"system": {
"value": "urn:oid:1.3.6.1.4.1.19126.3"
},
"value": {
"value": "Y3454867M"
}
},
{
"system": {
"value": "urn:oid:2.16.724.4.9.10.2"
},
"value": {
"value": "108505134"
}
}
]
}
]
I need to pick only .identifier[where .system.value == "urn:oid:1.3.6.1.4.1.19126.3"] and project .identifier.value.value.
Desired output:
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": "Y3454867M"
}
]
I've been playing with map and select but I don't quite figure out what's the right way to get it.
Any ideas?
This approach uses first to get the first result, in case there is more than one array item matching the criteria.
jq --arg v "urn:oid:1.3.6.1.4.1.19126.3" '
map(.identifier |= first(.[] | select(.system.value == $v).value.value))
'
[
{
"id": "9f0e27fe-3b8f-4857-8e1d-e57e7a3f4c31",
"identifier": "Y3454867M"
}
]
Demo
Right on the money with the good ol' select tool, since you need data from an arbitrary index. I fumbled a bit before I unwrapped the inner array that gets piped to my select.
jq -r '.[] | [{id: .id, identifier: .identifier | .[] | select(.system.value | contains("urn:oid:1.3.6.1.4.1.19126.3")) | .value.value }]'
Still new to jq myself, so any feedback is welcome.

jq - extract multiple fields from a list, with a nested list of key/value pairs

I have the following structure:
{
"Subnets": [
{
"SubnetId": "foo1",
"Id": "bar1",
"Tags": [
{
"Key": "Name",
"Value": "foo"
},
{
"Key": "Status",
"Value": "dev"
}
]
},
{
"SubnetId": "foo2",
"Id": "bar2",
"Tags": [
{
"Key": "Name",
"Value": "foo"
},
{
"Key": "Status",
"Value": "dev"
}
]
}
]
}
I can extract multiple keys at the "top level" like so:
cat subnets.json| jq '.Subnets[] | "\(.Id) \(.SubnetId)"'
Anyone know how I can also display one of the tags by key name, let's say I also want the Status tag displayed on the same line as the Id and SubnetId.
Thx for any help,
Is this what you are looking for?
jq '.Subnets[] | "\(.Id) \(.SubnetId) \(.Tags | from_entries | .Status)"' subnets.json

JQ filter and output format

For an input below:
[{
"commit": {
"author": {
"name": "Stephen Dolan",
"email": "mu#netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"committer": {
"name": "Stephen Dolan",
"email": "mu#netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161"
"url":"https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f"
},
{
...
}
}]
How can JQ generate a delimited string from different objects as shown below?
"Stephen Dolan", "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f", "2013-06-22T16:30:59Z"
Collect the fields you want in an array and use #csv to convert to a CSV row. Make sure you get the raw output.
jq -r '.[] | [ .commit.author.name, .commit.url, .commit.author.date ] | #csv' input.json

Resources