jq:嵌套对象,提取顶级id并从内部对象中提取值

时间:2014-12-19 08:46:41

标签: json bash jq

鉴于以下xample.json;

[
 {
  "id": 12345678,
  "stuff": { "book": "shelf", "hook": "line", "took": "off", "info-spec": 12 },
  "votes": 23
 },
 {
  "id": 12345679,
  "stuff": { "book": "maker", "hook": "sinker", "took": "pisin", "info-spec": 23 },
  "votes": 1
 }
]

我可以轻松地提取idvotes

$ jq '.[] | { id, votes }' xample.json
{
  "votes": 23,
  "id": 12345678
}
{
  "votes": 1,
  "id": 12345679
}

但是查询提取idstuff.info-spec会是什么样子?显而易见的(对我而言)语法根本不起作用:

$ jq '.[] | { id, stuff.info-spec }' xample.json
error: syntax error, unexpected '.', expecting '}'
.[] | { id, stuff.info-spec }
                 ^
1 compile error

我也试过了stuff[info-spec]stuff["info-spec"]但是,好吧,我似乎根本不知道应该怎么做。

密钥名称中的破折号似乎使问题更加复杂,但我的理解有限,我可以用双引号来解决这个问题。

$ sed 's/votes/vo-tes/g' xample.json | jq '.[] | { id, "vo-tes" }'

给出预期的输出(即类似于上面没有短划线的" vo-tes")。

我可以提取book

$ jq '.[] | .stuff.book' xample.json

但又无法弄清楚idbook的语法;但是,我无法使用相同的语法提取info-spec

$ jq '.[] | .stuff."info-spec"' xample.json
error: syntax error, unexpected QQSTRING_START, expecting IDENT
.[] | .stuff."info-spec"
             ^
1 compile error

如果我取出引号,则错误消息(可预测地)不同:

$ jq '.[] | .stuff.info-spec' xample.json
error: spec is not defined
.[] | .stuff.info-spec
                  ^^^^
1 compile error

但是,嘿,这有效:

$ jq '.[] | .stuff["info-spec"] ' xample.json
12
23

此示例的所需输出是

{
  "info-spec": 12,
  "id": 12345678
}
{
  "info-spec": 23,
  "id": 12345679
}

我已经查看了FAQjq Cookbook,但我似乎找不到任何有关"提升"的语法的内容。来自另一个对象内的对象内的项目。

2 个答案:

答案 0 :(得分:12)

有趣的是,这个问题确实是" - "这个角色对我有用:

jq '.[] | { id, "info-spec": .stuff."info-spec" }' xample.json
{
  "id": 12345678,
  "info-spec": 12
}
{
  "id": 12345679,
  "info-spec": 23
}

然而你的jq似乎不喜欢这种语法,因为它突破了以下内容而我的不会:

jq '.[] | .stuff."info-spec"' xample.json
12
23

我用:

jq --version
jq-1.4

编辑:看起来像版本问题< 1.4确实: https://github.com/stedolan/jq/issues/38

答案 1 :(得分:4)

我设法搞清楚了。

$ jq '.[] | { id, "info-spec": .stuff["info-spec"] }' xample.json
{
  "info-spec": 12,
  "id": 12345678
}
{
  "info-spec": 23,
  "id": 12345679
}

这里的关键似乎是使用newkey: .complex["key"]符号来解除。