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
}