我只是在学习jq,在这里有点困惑。假设我有一个名为testcite.json
的文件,如下所示:
[
{
"id": "JoeSchmoe2020",
"abstract": "Here's some junk",
"author": [
{
"family": "Scmoe",
"given": "Joe"
},
{
"family": "Smith",
"given": "Sally"
}
],
"title": "I wrote words!"
},
{
"id": "EdithJones2020",
"abstract": "It's an abstract",
"author": [
{
"family": "Jones",
"given": "Edith"
},
{
"family": "Wilson",
"given": "Eric"
}
],
"title": "These are more words!"
}
]
假设我想把它转换成这样的东西:
[
{
"author": [
"Scmoe",
"Smith"
],
"title": "I wrote words!"
},
{
"author": [
"Jones",
"Wilson"
],
"title": "These are more words!"
}
]
下面的命令可以让我得到我想要的。。。只要没有任何null。
cat testcite.json | jq '[.[] | {author: .author | map(.family), title}]'
但一旦出现空值,它就会爆炸。假设我更改了JSON:
[
{
"id": "JoeSchmoe2020",
"abstract": "Here's some junk",
"author": [
{
"family": "Scmoe",
"given": "Joe"
},
{
"family": "Smith",
"given": "Sally"
}
],
"title": "I wrote words!"
},
{
"id": "EdithJones2020",
"abstract": "It's an abstract",
"author": null,
"title": "These are more words!"
}
]
然后,当我运行相同的命令时,我希望得到的是类似的东西
[
{
"author": [
"Scmoe",
"Smith"
],
"title": "I wrote words!"
},
{
"author": [],
"title": "These are more words!"
}
]
(我也很乐意用null来代替空列表(。
不幸的是,相反,我得到了错误:
jq: error (at <stdin>:23): Cannot iterate over null (null)
我试过在问号中分散:
cat testcite.json | jq '[.[] | {author: .author | map(.family?), title}]'
只是产生相同的错误。
cat testcite.json | jq '[.[] | {author: .author | map(.family)?, title}]'
产生语法错误:
jq: error: syntax error, unexpected '?', expecting '}' (Unix shell quoting issues?) at <top-level>, line 1:
[.[] | {author: .author | map(.family)?, title}]
jq: 1 compile error
有没有什么方法可以让值提取只合理地处理null?
一个简单的解决方案是测试null
,例如
[.[]
| {author, title}
| .author |= if . then map(.family) else [] end
]
或类似:
map({author: (.author
| if type == "array"
then map(.family)
else [] end),
title} )