如何使用jq按文件名聚合多个JSON文件中的数据?
使用jq聚合多个JSON文件中的城市数据
可以用jq实现你想要的JSON数据聚合需求,以下是具体方案:
基础聚合命令
针对你给出的输入文件,执行以下命令即可得到目标输出:
jq -n 'reduce inputs as $in ({}; reduce keys($in)[] as $city (.; .[$city] += { (input_filename | gsub("\\.json$"; "")): $in[$city] }))' run1.json run2.json
命令解释
-n:启动jq的“null输入”模式,确保从空对象开始构建结果,而非默认读取第一个文件作为初始值reduce inputs as $in ({}; ...):遍历所有传入的JSON文件,将每个文件内容存入变量$in,初始结果为{}reduce keys($in)[] as $city (.; ...):遍历当前文件中的每个城市键input_filename | gsub("\\.json$"; ""):获取当前处理文件的名称,并移除.json后缀(若不需要移除后缀,删掉| gsub("\\.json$"; "")即可).[$city] += { ... }:将当前文件中该城市的数值,以处理后的文件名为键,合并到结果对象的对应城市字段下
执行后输出结果如下:
{ "Paris": { "run1": 1, "run2": 7 }, "London": { "run1": 2, "run2": 8 }, "Perth": { "run2": 9 } }
过滤城市子集(可选)
如果需要确保所有文件只保留共同存在的城市,可以先收集所有文件的城市交集,再进行聚合:
jq -n ' # 第一步:收集所有文件的城市,计算交集 all_cities := [inputs | keys] | reduce .[] as $cities (.[0]; . intersect $cities) # 第二步:重新读取文件,只聚合交集内的城市 | reduce inputs as $in ({}; reduce ($in | keys[] | select(. as $city | $city | IN($all_cities[]))) as $city (.; .[$city] += { (input_filename | gsub("\\.json$"; "")): $in[$city] } ) )' run1.json run2.json
这个命令会先计算出所有文件都包含的城市(示例中为Paris和London),再只对这些城市进行聚合。
内容的提问来源于stack exchange,提问作者Felix Dombek
相关产品推荐
相关产品推荐

