Create object starting from a list of string with jq.

huangapple go评论56阅读模式
英文:

Create object starting from a list of string with jq

问题

我理解你的请求,以下是翻译好的部分:

{
  "nonprod/global": [
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/eu": [
    "prod/eu/app/prod01"
  ],
  
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ]
}

如果你有其他翻译需求,请告诉我。

英文:

I would like to create a json object starting with a list of string in json format as the following

[
  "nonprod/global/app/sit01",
  "nonprod/global/app/dev02",
  "prod/na/app/prod01",
  "test/eu/app/cust01",
  "nonprod/global/app/dev03"
]

What I would like to obtain is a map of lists of strings which would have as key the first two words of the string from the list and as value the strings that starts with that specific key.

I've tried the following:

jq 'reduce (.[] | capture("(?<env_type>([^/]*/[^/]*))").env_type as $key | {($key) : [.]}) as $item ({}; . *= $item)'

And obtained:

{
  "nonprod/global": [
    "nonprod/global/app/dev03"
  ],
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ],
  "prod/eu": [
    "prod/eu/app/prod01"
  ]
}

I'm expecting:

{
  "nonprod/global":[
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/eu":[
    "prod/eu/app/prod01"
  ],
  
  "prod/na":[
    "prod/na/app/prod01"
  ],
  "test/eu":[
    "test/eu/app/cust01"
  ]
}

答案1

得分: 2

"which would have as key the first two words" 可以翻译为:"将前两个单词作为键"

"You can define a function that splits at the second slash, then usi it to group_by the input array, creating an array of arrays, then use INDEX to turn it into an object, using the same function on the first item." 可以翻译为:"您可以定义一个在第二个斜杠处拆分的函数,然后将其用于对输入数组进行分组,创建一个数组的数组,然后使用 INDEX 将其转换为对象,在第一个项目上使用相同的函数。"

以下是代码部分,不需要翻译:

def f: .[:indices("/")[1]];
group_by(f) | INDEX(first | f)
{
  "nonprod/global": [
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ]
}

Demo

英文:

> which would have as key the first two words

You can define a function that splits at the second slash, then usi it to group_by the input array, creating an array of arrays, then use INDEX to turn it into an object, using the same function on the first item.

def f: .[:indices("/")[1]];
group_by(f) | INDEX(first | f)
{
  "nonprod/global": [
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ]
}

Demo

答案2

得分: 2

使用 += 向数组添加元素。如果键不存在,jq将即时创建它(null + []的结果是[]):

reduce (.[] | capture("^(?<env>(?<type>[^/]*/[^/]*).*)$")) as {$env, $type} 
({}; .[$type] += [$env])
{
  "nonprod/global": [
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ]
}

演示

英文:

Use += to add to an array. If the key doesn't exist, jq will create it on the fly (null + [] evaluates to []):

reduce (.[] | capture(&quot;^(?&lt;env&gt;(?&lt;type&gt;[^/]*/[^/]*).*)$&quot;)) as {$env, $type} 
({}; .[$type] += [$env])
{
  &quot;nonprod/global&quot;: [
    &quot;nonprod/global/app/sit01&quot;,
    &quot;nonprod/global/app/dev02&quot;,
    &quot;nonprod/global/app/dev03&quot;
  ],
  &quot;prod/na&quot;: [
    &quot;prod/na/app/prod01&quot;
  ],
  &quot;test/eu&quot;: [
    &quot;test/eu/app/cust01&quot;
  ]
}

Demo

huangapple
  • 本文由 发表于 2023年5月23日 00:40:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76308296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定