在 jq 中使用解构替代运算符 ?//
Using the Destructuring Alternative Operator ?// in jq
在最新的 jq 1.6 版本中有一个功能 Destructuring Alternative Operator: ?// 我正试图用它来解析我的 笨拙地转换 XML.
这是我在 jq play:
上玩过的简化示例
{"data":[
{"fruit":"orange","details": {"colour":"orange"}},
{"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}
关键点有时 details
是一个对象,有时它是一个对象数组,引用文档 “我们可以使用解构替代运算符来处理这种结构变化只是
如果我更改输入数据,那么 details
始终是一个数组,我可以轻松创建 the output I want
.data[] | "\(.fruit) - \(.details[].colour)"
{"data":[
{"fruit":"orange","details": [{"colour":"orange"}]},
{"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}
"orange - orange"
"apple - red"
"apple - green"
然而,使用带有 ?// 的原始数据最好的 I can come up with 是:
.data[] as {$fruit, details: $colour} ?// {$fruit, details: $colour} | "\($fruit) - \($colour)"
"orange - {\"colour\":\"orange\"}"
"apple - [{\"colour\":\"red\"},{\"colour\":\"green\"}]"
and this (which is pretty much a copy of one of the examples):
.data[] as {$fruit, details: {$colour}} ?// {$fruit, details: [{$colour}]} | "\($fruit) - \($colour)"
"orange - orange"
"apple - red"
有 solutions using if else 但我特别感兴趣的是这个功能是如何工作的,以及我需要做什么才能得到它来创建我想要的输出。
生成您期望的输出的一种方法是使用 ? //
而不是 ?//
:
.data[]
| (.details | (.colour? // (.[] | .colour))) as $colour
| "\(.fruit) - \($colour)"
至于 ?//
,您可能找错了树:destructuring-alternative 运算符不是 stream-oriented。也就是说,当 non-empty 数组与 [$foo] 匹配时,$foo 只会匹配数组中的第一项,而不匹配序列中的项。
但是,如果您真的想使用 ?//
,对于您的特定情况,您可以这样写:
.data[]
| .details as [$colour1, $colour2] ?// $colour1
| "\(.fruit) - \($colour1|.colour)",
"\(.fruit) - \($colour2//empty|.colour)"
在最新的 jq 1.6 版本中有一个功能 Destructuring Alternative Operator: ?// 我正试图用它来解析我的 笨拙地转换 XML.
这是我在 jq play:
上玩过的简化示例{"data":[
{"fruit":"orange","details": {"colour":"orange"}},
{"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}
关键点有时 details
是一个对象,有时它是一个对象数组,引用文档 “我们可以使用解构替代运算符来处理这种结构变化只是
如果我更改输入数据,那么 details
始终是一个数组,我可以轻松创建 the output I want
.data[] | "\(.fruit) - \(.details[].colour)"
{"data":[
{"fruit":"orange","details": [{"colour":"orange"}]},
{"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}
"orange - orange"
"apple - red"
"apple - green"
然而,使用带有 ?// 的原始数据最好的 I can come up with 是:
.data[] as {$fruit, details: $colour} ?// {$fruit, details: $colour} | "\($fruit) - \($colour)"
"orange - {\"colour\":\"orange\"}"
"apple - [{\"colour\":\"red\"},{\"colour\":\"green\"}]"
and this (which is pretty much a copy of one of the examples):
.data[] as {$fruit, details: {$colour}} ?// {$fruit, details: [{$colour}]} | "\($fruit) - \($colour)"
"orange - orange"
"apple - red"
有 solutions using if else 但我特别感兴趣的是这个功能是如何工作的,以及我需要做什么才能得到它来创建我想要的输出。
生成您期望的输出的一种方法是使用 ? //
而不是 ?//
:
.data[]
| (.details | (.colour? // (.[] | .colour))) as $colour
| "\(.fruit) - \($colour)"
至于 ?//
,您可能找错了树:destructuring-alternative 运算符不是 stream-oriented。也就是说,当 non-empty 数组与 [$foo] 匹配时,$foo 只会匹配数组中的第一项,而不匹配序列中的项。
但是,如果您真的想使用 ?//
,对于您的特定情况,您可以这样写:
.data[]
| .details as [$colour1, $colour2] ?// $colour1
| "\(.fruit) - \($colour1|.colour)",
"\(.fruit) - \($colour2//empty|.colour)"