如何从jq中现有json中的值输出带有新键名的json

时间:2021-11-13 23:47:01

I have an existing json which have a from like this:

我有一个现有的json,有这样的:

{
  "arg1": "Admin",
  "arg2": 0,
  "data": [
    {
      "arg3": "11",
      "user": "user1",
      "age": 51,
      "arg4": "11"
    },
    {
      "arg3": "22",
      "user": "user2",
      "age": 52,
      "arg4": "22"
    },
    {
      "arg3": "33",
      "user": "user3",
      "age": 53,
      "arg4": "33"
    },
    {
      "arg3": "44",
      "user": "user4",
      "age": 54,
      "arg4": "44"
    }
  ]
}

Then I try this command:

然后我尝试这个命令:

$ cat tmp.json|jq '.data|.[]|{user,age}'
{
  "user": "user1",
  "age": 51,
}
{
  "user": "user2",
  "age": 52,
}
{
  "user": "user3",
  "age": 53,
}
{
  "user": "user4",
  "age": 54,
}

What I expect to output is:

我期望输出的是:

{
  "department": "Admin",
  "user_age": {
    "user1": "51",
    "user2": "52",
    "user3": "53",
    "user4": "54"
  },
  "year": 2016
}

In jq's manual, my request is close to example 23.

在jq的手册中,我的请求接近示例23。

So I tried to use from_entries function

所以我尝试使用from_entries函数

cat tmp.json|jq '.data|.[]|{user,age}|from_entries'

but get this error:

但得到这个错误:

jq: error (at :30): Cannot index string with string "key"

jq:error(at:30):无法用字符串“key”索引字符串

I know this is because of its format not equal an entry.

我知道这是因为它的格式不等于条目。

So, what should I do to convert to the expected output?

那么,我该怎么做才能转换成预期的输出呢?

3 个解决方案

#1


1  

from_entries expects an array of objects with key and value properties. You are however generating separate objects with user and age properties which just would not work. First of all, you would need to make sure that the properties are in an array, then have the separate key/value pairs for each of the values you want in the array.

from_entries需要一个具有键和值属性的对象数组。但是,您正在生成具有用户和年龄属性的单独对象,这些对象无法正常工作。首先,您需要确保属性在数组中,然后为数组中所需的每个值分配单独的键/值对。

With that said, you don't really need to use entries to build out the result, it's not the right tool for the job. You just want to pull some properties from each of the data objects and add to another object mapping users to ages. There's many ways this can be achieved, I would use reduce to accomplish this.

话虽如此,你并不需要使用条目来构建结果,它不适合这项工作。您只想从每个数据对象中提取一些属性,并添加到将用户映射到年龄的另一个对象。有很多方法可以实现,我会使用reduce来实现这一目标。

reduce .data[] as $d ({}; .[$d.user] = $d.age)

To get your final result, just combine the parts you need into the object you're requiring. I'm not sure where you got that 2016 from, I'm assuming it's just hardcoded.

要获得最终结果,只需将您需要的部分组合到您需要的对象中。我不确定你从哪里得到2016年,我假设它只是硬编码。

{department: .arg1, user_age: (reduce .data[] as $d ({}; .[$d.user] = $d.age)), year: 2016}

#2


1  

you can also try:

你也可以尝试:

cat tmp.json|jq '{department: .arg1, user_age: (.data|map({(.user): .age})|add), year: 2016}'

or

要么

cat tmp.json|jq '{department: .arg1, user_age: .data|map({(.user): .age})|add, year: 2016}'

#3


0  

As Jeff explained, from_entries expects input of the form

正如杰夫解释的那样,from_entries期望输入表格

[ {key:xxx, value:yyy} ]

so Hao's filter

所以郝的过滤器

.data | .[] | {user,age} | from_entries

requires two small modifications to generate the desired user_age object:

需要两个小的修改才能生成所需的user_age对象:

  • the values must be {key,value} objects
  • 值必须是{key,value}对象
  • the values need to be collected into an array
  • 需要将值收集到数组中

e.g.

例如

.data | [.[]|{key:user, value:age|tostring}] | from_entries

(we include tostring because the values in the example output are strings)

(我们包括tostring,因为示例输出中的值是字符串)

But since [ .[]| ... ] is the same as map(...) this could be written

但是因为[。[] | ...]与map(...)相同,可以写入

.data | map({key:user, value:age|tostring}) | from_entries

Here is a complete solution:

这是一个完整的解决方案:

{
  "department": .arg1,
  "user_age": .data | map({key:.user, value:.age|tostring}) | from_entries,
  "year": 2016
}

Sample output

样本输出

{
  "department": "Admin",
  "user_age": {
    "user1": "51",
    "user2": "52",
    "user3": "53",
    "user4": "54"
  },
  "year": 2016
}

#1


1  

from_entries expects an array of objects with key and value properties. You are however generating separate objects with user and age properties which just would not work. First of all, you would need to make sure that the properties are in an array, then have the separate key/value pairs for each of the values you want in the array.

from_entries需要一个具有键和值属性的对象数组。但是,您正在生成具有用户和年龄属性的单独对象,这些对象无法正常工作。首先,您需要确保属性在数组中,然后为数组中所需的每个值分配单独的键/值对。

With that said, you don't really need to use entries to build out the result, it's not the right tool for the job. You just want to pull some properties from each of the data objects and add to another object mapping users to ages. There's many ways this can be achieved, I would use reduce to accomplish this.

话虽如此,你并不需要使用条目来构建结果,它不适合这项工作。您只想从每个数据对象中提取一些属性,并添加到将用户映射到年龄的另一个对象。有很多方法可以实现,我会使用reduce来实现这一目标。

reduce .data[] as $d ({}; .[$d.user] = $d.age)

To get your final result, just combine the parts you need into the object you're requiring. I'm not sure where you got that 2016 from, I'm assuming it's just hardcoded.

要获得最终结果,只需将您需要的部分组合到您需要的对象中。我不确定你从哪里得到2016年,我假设它只是硬编码。

{department: .arg1, user_age: (reduce .data[] as $d ({}; .[$d.user] = $d.age)), year: 2016}

#2


1  

you can also try:

你也可以尝试:

cat tmp.json|jq '{department: .arg1, user_age: (.data|map({(.user): .age})|add), year: 2016}'

or

要么

cat tmp.json|jq '{department: .arg1, user_age: .data|map({(.user): .age})|add, year: 2016}'

#3


0  

As Jeff explained, from_entries expects input of the form

正如杰夫解释的那样,from_entries期望输入表格

[ {key:xxx, value:yyy} ]

so Hao's filter

所以郝的过滤器

.data | .[] | {user,age} | from_entries

requires two small modifications to generate the desired user_age object:

需要两个小的修改才能生成所需的user_age对象:

  • the values must be {key,value} objects
  • 值必须是{key,value}对象
  • the values need to be collected into an array
  • 需要将值收集到数组中

e.g.

例如

.data | [.[]|{key:user, value:age|tostring}] | from_entries

(we include tostring because the values in the example output are strings)

(我们包括tostring,因为示例输出中的值是字符串)

But since [ .[]| ... ] is the same as map(...) this could be written

但是因为[。[] | ...]与map(...)相同,可以写入

.data | map({key:user, value:age|tostring}) | from_entries

Here is a complete solution:

这是一个完整的解决方案:

{
  "department": .arg1,
  "user_age": .data | map({key:.user, value:.age|tostring}) | from_entries,
  "year": 2016
}

Sample output

样本输出

{
  "department": "Admin",
  "user_age": {
    "user1": "51",
    "user2": "52",
    "user3": "53",
    "user4": "54"
  },
  "year": 2016
}