如何根据 jq 现有 json 中的值输出带有新键名的 json
How can I output a json with the new key name from the value in an existing json by jq
我有一个现有的 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"
}
]
}
然后我尝试这个命令:
$ cat tmp.json|jq '.data|.[]|{user,age}'
{
"user": "user1",
"age": 51,
}
{
"user": "user2",
"age": 52,
}
{
"user": "user3",
"age": 53,
}
{
"user": "user4",
"age": 54,
}
我期望输出的是:
{
"department": "Admin",
"user_age": {
"user1": "51",
"user2": "52",
"user3": "53",
"user4": "54"
},
"year": 2016
}
在jq的手册中,我的要求接近example 23。
所以我尝试使用from_entries
函数
cat tmp.json|jq '.data|.[]|{user,age}|from_entries'
但出现此错误:
jq: error (at :30): Cannot index string with string "key"
我知道这是因为它的格式不等于条目。
那么,我应该怎么做才能转换成预期的输出?
from_entries
需要一个具有 key
和 value
属性的对象数组。但是,您正在生成具有 user
和 age
属性的单独对象,这是行不通的。首先,您需要确保属性在一个数组中,然后为数组中您想要的每个值设置单独的 key/value 对。
话虽如此,您实际上并不需要使用条目来构建结果,它不是完成这项工作的正确工具。您只想从每个数据对象中提取一些属性并添加到另一个对象,将用户映射到年龄。有很多方法可以实现,我会使用 reduce
来实现。
reduce .data[] as $d ({}; .[$d.user] = $d.age)
要获得最终结果,只需将您需要的部分组合到您需要的对象中即可。我不确定你从哪里得到 2016 年的,我假设它只是硬编码的。
{department: .arg1, user_age: (reduce .data[] as $d ({}; .[$d.user] = $d.age)), year: 2016}
你也可以试试:
cat tmp.json|jq '{department: .arg1, user_age: (.data|map({(.user): .age})|add), year: 2016}'
或
cat tmp.json|jq '{department: .arg1, user_age: .data|map({(.user): .age})|add, year: 2016}'
因为 Jeff explained, from_entries 期望输入形式
[ {key:xxx, value:yyy} ]
所以Hao的过滤器
.data | .[] | {user,age} | from_entries
需要两个小修改才能生成所需的 user_age
对象:
- 值必须是
{key,value}
个对象
- 需要将值收集到数组中
例如
.data | [.[]|{key:user, value:age|tostring}] | from_entries
(我们包括 tostring
因为示例输出中的值是字符串)
但由于 [ .[]| ... ]
与 map(...)
相同,因此可以这样写
.data | map({key:user, value:age|tostring}) | from_entries
这是一个完整的解决方案:
{
"department": .arg1,
"user_age": .data | map({key:.user, value:.age|tostring}) | from_entries,
"year": 2016
}
示例输出
{
"department": "Admin",
"user_age": {
"user1": "51",
"user2": "52",
"user3": "53",
"user4": "54"
},
"year": 2016
}
我有一个现有的 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"
}
]
}
然后我尝试这个命令:
$ cat tmp.json|jq '.data|.[]|{user,age}'
{
"user": "user1",
"age": 51,
}
{
"user": "user2",
"age": 52,
}
{
"user": "user3",
"age": 53,
}
{
"user": "user4",
"age": 54,
}
我期望输出的是:
{
"department": "Admin",
"user_age": {
"user1": "51",
"user2": "52",
"user3": "53",
"user4": "54"
},
"year": 2016
}
在jq的手册中,我的要求接近example 23。
所以我尝试使用from_entries
函数
cat tmp.json|jq '.data|.[]|{user,age}|from_entries'
但出现此错误:
jq: error (at :30): Cannot index string with string "key"
我知道这是因为它的格式不等于条目。
那么,我应该怎么做才能转换成预期的输出?
from_entries
需要一个具有 key
和 value
属性的对象数组。但是,您正在生成具有 user
和 age
属性的单独对象,这是行不通的。首先,您需要确保属性在一个数组中,然后为数组中您想要的每个值设置单独的 key/value 对。
话虽如此,您实际上并不需要使用条目来构建结果,它不是完成这项工作的正确工具。您只想从每个数据对象中提取一些属性并添加到另一个对象,将用户映射到年龄。有很多方法可以实现,我会使用 reduce
来实现。
reduce .data[] as $d ({}; .[$d.user] = $d.age)
要获得最终结果,只需将您需要的部分组合到您需要的对象中即可。我不确定你从哪里得到 2016 年的,我假设它只是硬编码的。
{department: .arg1, user_age: (reduce .data[] as $d ({}; .[$d.user] = $d.age)), year: 2016}
你也可以试试:
cat tmp.json|jq '{department: .arg1, user_age: (.data|map({(.user): .age})|add), year: 2016}'
或
cat tmp.json|jq '{department: .arg1, user_age: .data|map({(.user): .age})|add, year: 2016}'
因为 Jeff explained, from_entries 期望输入形式
[ {key:xxx, value:yyy} ]
所以Hao的过滤器
.data | .[] | {user,age} | from_entries
需要两个小修改才能生成所需的 user_age
对象:
- 值必须是
{key,value}
个对象 - 需要将值收集到数组中
例如
.data | [.[]|{key:user, value:age|tostring}] | from_entries
(我们包括 tostring
因为示例输出中的值是字符串)
但由于 [ .[]| ... ]
与 map(...)
相同,因此可以这样写
.data | map({key:user, value:age|tostring}) | from_entries
这是一个完整的解决方案:
{
"department": .arg1,
"user_age": .data | map({key:.user, value:.age|tostring}) | from_entries,
"year": 2016
}
示例输出
{
"department": "Admin",
"user_age": {
"user1": "51",
"user2": "52",
"user3": "53",
"user4": "54"
},
"year": 2016
}