-4

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.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Mickey Perlstein
  • 2,508
  • 2
  • 30
  • 37
  • 1
    Please provide in the question a sample of the JSON output of just `yc vpc networks list --format json`, as well as an according output as you expect it from the `jq` command. – pmf Jan 04 '23 at 12:55
  • Does this answer your question? [jq: selecting subset of keys from nested object](https://stackoverflow.com/questions/46876940/jq-selecting-subset-of-keys-from-nested-object) – 0stone0 Jan 04 '23 at 13:07
  • Does this answer your question? [How do I remove all keys except one with jq?](https://stackoverflow.com/questions/27838154/how-do-i-remove-all-keys-except-one-with-jq) – 0stone0 Jan 04 '23 at 13:08
  • no, both those questions are not simple enough, i know there is a more elegant solution. this is for a course in devops and these solutions are convoluted – Mickey Perlstein Jan 04 '23 at 13:18
  • The second links accepted answer is excatly what you're looking for, but you'll need to add `folder_id`. – 0stone0 Jan 04 '23 at 13:21
  • Regardig "[Try out your assumptions here](https://jqplay.org/s/02MGBzxT349)": Have you tried ticking the `Slurp` option in the top right corner? [Demo](https://jqplay.org/s/hKjUBDDVTtN) – pmf Jan 04 '23 at 13:46
  • What's the output of `yc ...` without running it through `jq '.[]'` first? Without knowing the input to jq, it's almost impossible to give a useful answer. – knittl Jan 04 '23 at 13:59
  • it's in the question. anyway this question was solved. thanks – Mickey Perlstein Jan 04 '23 at 14:28
  • 3
    @MickeyPerlstein no, it is not in the question. Your question shows the output _after_ piping through jq. (If this is in fact the output of `yc` only (without `|jq`), then the question is written in a _very_ confusing way) – knittl Jan 04 '23 at 15:02

3 Answers3

1

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

0stone0
  • 34,288
  • 4
  • 39
  • 64
  • doesn't work. you setup the json to be an array. my output is npt a json array. its a multiline of jsons. look at my output example. - for simple filters i wouldnt ask tyhe question. – Mickey Perlstein Jan 04 '23 at 13:31
  • The 'output' in your question is without any jq commands? Thats not clear, I'll change my answer – 0stone0 Jan 04 '23 at 13:32
1

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  })'
[
  {...},
  {...}
]
knittl
  • 246,190
  • 53
  • 318
  • 364
  • Thanks for the detailed explanation. this is definately a great answer, unfortunately the answer bellow is EXACTLY what I needed, so it is the accepted answer - but this is definately a Q&A i will use in the devops course. thanks!@@! – Mickey Perlstein Jan 04 '23 at 14:26
0

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

pmf
  • 24,478
  • 2
  • 22
  • 31