给定以下形式的JSON流:
{ "a": 10, "b": 11 } { "a": 20, "b": 21 } { "a": 30, "b": 31 }
Run Code Online (Sandbox Code Playgroud)
我想对每个对象中的值求和并输出一个对象,即:
{ "a": 60, "b": 63 }
Run Code Online (Sandbox Code Playgroud)
我猜这可能需要将上面的对象列表展平成一个对数组,[name, value]
然后使用这些值进行求和,reduce
但是使用的语法文档reduce
是可悲的.
Jef*_*ado 23
除非您的jq有inputs
,否则您将不得不使用-s
旗帜将对象啜饮.然后你将不得不做大量的操作:
map(to_entries)
| add
| group_by(.key)
| map({
key: .[0].key,
value: map(.value) | add
})
| from_entries
Run Code Online (Sandbox Code Playgroud)
使用jq 1.5,可以大大改善:你可以消除啜饮,直接阅读inputs
.
$ jq -n '
reduce (inputs | to_entries[]) as {$key,$value} ({}; .[$key] += $value)
' input.json
Run Code Online (Sandbox Code Playgroud)
由于我们只是在每个对象中累积所有值,因此只需运行所有输入的键/值对,并将它们全部添加起来就更容易了.
Ole*_*rov 10
我在列出来自 GitHub 的所有工件时遇到了同样的问题(请参阅此处了解详细信息)并想对它们的大小求和。
curl https://api.github.com/repos/:owner/:repo/actions/artifacts \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token <your_pat_here>" \
| jq '.artifacts | map(.size_in_bytes) | add'
Run Code Online (Sandbox Code Playgroud)
输入:
{
"total_count": 3,
"artifacts": [
{
"id": 0000001,
"node_id": "MDg6QXJ0aWZhY3QyNzUxNjI1",
"name": "artifact-1",
"size_in_bytes": 1,
"url": "https://api.github.com/repos/:owner/:repo/actions/artifacts/2751625",
"archive_download_url": "https://api.github.com/repos/:owner/:repo/actions/artifacts/2751625/zip",
"expired": false,
"created_at": "2020-03-10T18:21:23Z",
"updated_at": "2020-03-10T18:21:24Z"
},
{
"id": 0000002,
"node_id": "MDg6QXJ0aWZhY3QyNzUxNjI0",
"name": "artifact-2",
"size_in_bytes": 2,
"url": "https://api.github.com/repos/:owner/:repo/actions/artifacts/2751624",
"archive_download_url": "https://api.github.com/repos/:owner/:repo/actions/artifacts/2751624/zip",
"expired": false,
"created_at": "2020-03-10T18:21:23Z",
"updated_at": "2020-03-10T18:21:24Z"
},
{
"id": 0000003,
"node_id": "MDg6QXJ0aWZhY3QyNzI3NTk1",
"name": "artifact-3",
"size_in_bytes": 3,
"url": "https://api.github.com/repos/docker/mercury-ui/actions/artifacts/2727595",
"archive_download_url": "https://api.github.com/repos/:owner/:repo/actions/artifacts/2727595/zip",
"expired": false,
"created_at": "2020-03-10T08:46:08Z",
"updated_at": "2020-03-10T08:46:09Z"
}
]
}
Run Code Online (Sandbox Code Playgroud)
输出:
6
Run Code Online (Sandbox Code Playgroud)
另一种很好地说明jq功能的方法是使用一个名为"sum"的过滤器,定义如下:
def sum(f): reduce .[] as $row (0; . + ($row|f) );
Run Code Online (Sandbox Code Playgroud)
为了解决手头的特定问题,可以使用-s
上面提到的(--slurp)选项以及表达式:
{"a": sum(.a), "b": sum(.b) } # (2)
Run Code Online (Sandbox Code Playgroud)
标记为(2)的表达式仅计算两个指定的和,但很容易推广,例如如下:
# Produce an object with the same keys as the first object in the
# input array, but with values equal to the sum of the corresponding
# values in all the objects.
def sumByKey:
. as $in
| reduce (.[0] | keys)[] as $key
( {}; . + {($key): ($in | sum(.[$key]))})
;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15124 次 |
最近记录: |