我有一个 SQL 结果集导出为 JSON,采用数组中 1:1 映射的形式。
例如
[
{
"subject": "Accounting",
"level": "A Level"
},
{
"subject": "Accounting",
"level": "IB"
},
{
"subject": "Accounting",
"level": "University"
},
{
"subject": "Accounting",
"level": "GCSE"
},
{
"subject": "Accounting",
"level": "Mentoring"
},
{
"subject": "Accounting",
"level": "13 Plus"
},
{
"subject": "Accounting",
"level": "11 Plus"
},
etc.....
我想将各个级别合并为一个主题键,如下所示:
[
"Accounting": ["A Level", "IB", "University"],
"Foo": ["Foo Intro", "Foo Basics", "Intermediate Foo"]
]
笔记:没有匿名对象
我怎样才能用jq实现这个目标?
答案1
给定
$ jq '.' file.json
[
{
"subject": "Accounting",
"level": "A Level"
},
{
"subject": "Foo",
"level": "IB"
},
{
"subject": "Accounting",
"level": "University"
},
{
"subject": "Foo",
"level": "GCSE"
},
{
"subject": "Accounting",
"level": "Mentoring"
},
{
"subject": "Accounting",
"level": "13 Plus"
},
{
"subject": "Foo",
"level": "11 Plus"
}
]
然后大量借钱使用汇总数据重塑 jq 数组
$ jq 'reduce .[] as $d (null; .[$d.subject] += [$d.level])' file.json
{
"Accounting": [
"A Level",
"University",
"Mentoring",
"13 Plus"
],
"Foo": [
"IB",
"GCSE",
"11 Plus"
]
}
注意:外层是一个对象而不是数组(如您的预期输出所示 - 它似乎不是有效的 JSON)。
答案2
我不知道你会如何做到这一点jq
(我发现用像 perl 这样的通用语言编写一些东西比学习像jq
......这样的单一用途工具更容易,如果我更频繁地使用 json 数据,它可能会是值得我花时间去学习比它最基本的用途更多的东西),但是使用 Perl 就很容易了JSON模块。
#!/usr/bin/perl
use strict;
use JSON;
# hash-of-arrays to hold an array of "level"s for each "subject"
my %merged;
# slurp the input into scalar string variable $text
my $text; { local $/; $text=<> }
my $json = JSON->new->allow_nonref;
my $data = $json->decode($text); # parse json text into $data arrayref
# loop over each row of $data and insert into %merged
foreach my $row (@$data) {
my $key = $row->{subject};
my $val = $row->{level};
push @{ $merged{$key} }, $val;
};
# pretty-print %merged as json
print $json->pretty->encode(\%merged), "\n";
示例输出:
$ ./merge-json.pl input.json
{
"Accounting" : [
"A Level",
"IB",
"University",
"GCSE",
"Mentoring",
"13 Plus",
"11 Plus"
],
"Foo" : [
"Foo Intro",
"Foo Basics",
"Intermediate Foo"
]
}
如果您运行的是 Debian 或 Ubuntu 或类似版本,您可以使用以下命令安装 JSON 模块sudo apt-get install libjson-perl libjson-xs-perl
(这应该安装 perl 本机版本和模块的编译速度更快的 C 版本,JSON::XS)。它可能也适用于其他发行版。否则,请使用 进行安装cpan
。
答案3
与以下方法不同的方法钢铁司机的是按键对数据进行分组subject
,然后将所有level
值收集为各自的数组下subject
。
以下使用与steeldriver相同的测试数据:
$ jq 'group_by(.subject) | map({ (first.subject): map(.level) }) | add' file
{
"Accounting": [
"A Level",
"University",
"Mentoring",
"13 Plus"
],
"Foo": [
"IB",
"GCSE",
"11 Plus"
]
}
最后add
合并前面创建的数组的元素map()
。