지도 배열의 값을 jq로 합산하려면 어떻게 해야 합니까?
다음 형식의 JSON 스트림이 지정됩니다.
{ "a": 10, "b": 11 } { "a": 20, "b": 21 } { "a": 30, "b": 31 }
각 객체의 값을 합산하여 단일 객체, 즉 다음과 같이 출력합니다.
{ "a": 60, "b": 63 }
아마도 이것은 위의 오브젝트 목록을 일련의 오브젝트로 평평하게 만들어야 할 것 같습니다.[name, value]
페어를 사용하여 값을 합산합니다.reduce
그러나 이 명령어를 사용하기 위한 구문에 대한 설명서는reduce
슬프다.
당신의 jq가inputs
, 를 사용하여 오브젝트를 후루룩 마셔야 합니다.-s
플래그. 그러면 상당한 양의 조작을 해야 합니다.
- 각 개체를 키/값 쌍에 매핑해야 합니다.
- 쌍을 단일 어레이로 평탄화
- 키별로 쌍을 그룹화합니다.
- 값을 누적하는 각 그룹을 단일 키/값 쌍으로 매핑합니다.
- 쌍을 개체에 다시 매핑합니다.
map(to_entries)
| add
| group_by(.key)
| map({
key: .[0].key,
value: map(.value) | add
})
| from_entries
jq 1.5를 사용하면 다음과 같이 대폭 개선될 수 있습니다.후루룩 거리지 말고 그냥 읽으시면 됩니다.inputs
직접적으로.
$ jq -n '
reduce (inputs | to_entries[]) as {$key,$value} ({}; .[$key] += $value)
' input.json
각 객체의 모든 값을 단순히 축적하는 것이기 때문에 모든 입력의 키/값 쌍을 실행한 후 모두 합산하는 것이 더 쉬워집니다.
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'
입력:
{
"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"
}
]
}
출력:
6
jq의 힘을 잘 보여주는 또 다른 접근법은 다음과 같이 정의된 "sum"이라는 이름의 필터를 사용하는 것입니다.
def sum(f): reduce .[] as $row (0; . + ($row|f) );
당면한 특정 문제를 해결하려면 다음 명령을 사용할 수 있습니다.-s
위에서 설명한 (--slurp) 옵션과 다음 식을 함께 사용합니다.
{"a": sum(.a), "b": sum(.b) } # (2)
(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]))})
;
언급URL : https://stackoverflow.com/questions/28484534/how-do-i-sum-the-values-in-an-array-of-maps-in-jq
'programing' 카테고리의 다른 글
ESLint - 오류:ES 모듈을 로드하려면 Import를 사용해야 합니다. (0) | 2023.04.04 |
---|---|
SqlDataReader에서 JSON으로 변환 (0) | 2023.03.25 |
PyMongo에서 .sort 사용 (0) | 2023.03.25 |
selectOneMenu ajax 이벤트 (0) | 2023.03.25 |
Angularjs - 인수를 디렉티브로 전달합니다. (0) | 2023.03.25 |