[英]How do I make this jq expression, which works in jq >= 1.5, backwards-compatible / correct for versions < 1.5
In any version (that i've tried) of jq >= 1.5
, this works fine . 在
jq >= 1.5
任何版本(我尝试过)中,都可以正常工作 。
In any version of jq <= 1.4
, I get the following error: 在任何版本的
jq <= 1.4
,都会出现以下错误:
error: syntax error, unexpected as, expecting FORMAT or QQSTRING_START
There's a lot of information around on the error: "expecting FORMAT or QQSTRING_START" , so far what I've seen has not applied here, I wonder if it's the as
that I am not implementing reliably 关于该错误,有很多信息: “ expecting FORMAT or QQSTRING_START” ,到目前为止,我所看到的并没有在这里应用,我想知道是否是
as
我没有可靠地实现
I can recreate the problem with this trivial code: (can be copied/pasted as is to test) 我可以使用以下普通代码来重新创建问题:(可以复制/粘贴以进行测试)
jq \ '(..|.liveBroadcastContent?'\ '| foreach . as $item (.; if $item == null then false else . end)) as $chanstatus '\ '| {location:"location", channel:"channelid", current_id:"vId", id_status:$chanstatus, url:"https://youtu.be/\("vId")"}' \ <<<'{"liveBroadcastContent":true}'
Desired result achieved on jq > 1.5
: 在
jq > 1.5
上获得所需的结果 :
{
"location": "location",
"channel": "channelid",
"current_id": "vId",
"id_status": true,
"url": "https://youtu.be/vId"
}
What it's supposed to do: 它应该做什么:
liveBroadcastContent
exists in the input: then output it's value in the id_status
key liveBroadcastContent
存在 liveBroadcastContent
:则将其值输出到id_status
键中 liveBroadcastContent
does not exist : then output false
in the id_status
key liveBroadcastContent
不存在 :则在id_status
键中输出false
Actual Input : 实际输入 :
This is what goes into the program when there is a live stream present. 这就是进入程序时, 有一个现场出现的流。
This is what goes into the program when there is no live streams 这就是进入程序时,有没有直播流
Hence I thought ..|.liveBroadcastContent?
因此,我以为
..|.liveBroadcastContent?
was the most reliable way to basically say " If this key appears somewhere in the data, please return it's value in <this> part of my fixed-format output data " 基本上是说“ 如果此键出现在数据中的某个位置 ,请在固定格式输出数据的<this>部分中返回它的值 ”是最可靠的方法。
Now that the application is obvious, please note that I am aware of using other methods such as checking the value of "totalResults"
, in combination with HTTP 200
, amongst others, however: 现在该应用程序已经很明显了,请注意,我知道我将结合使用
HTTP 200
和其他方法使用其他方法,例如检查"totalResults"
的值,但是:
jq
may be useful elsewhere and I'd like to address it as it. jq
此应用程序可能在其他地方有用,我想以此解决它。 liveBroadcastContent
liveBroadcastContent
EDIT: Just to clarify - this isn't about the behavior of jq
across versions (something that would belong in the jq
forums) - It's about making the most robust portable code. 编辑:只是为了澄清-这与跨版本的
jq
的行为无关 (属于jq
论坛)-与制作最健壮的可移植代码有关。 I tend to think that versions >1.5 are simply forgiving a poorly formed expression (which I'm trying to work out here) 我倾向于认为> 1.5的版本只是宽容了格式不正确的表达式(我正在此处尝试解决)
The reason your snippet fails in jq 1.4 is that foreach
was only introduced in version 1.5. 您的代码段在jq 1.4中失败的原因是
foreach
仅在版本1.5中引入。
I'm not sure that your program with foreach
is consistent with your stated requirements, which unfortunately are slightly unclear. 我不确定您的带有
foreach
的程序是否与您声明的要求一致,但不幸的是,这些要求还不清楚。 For example, what if the "liveBroadcastContent" key appears more than once in the input JSON entity? 例如,如果“ liveBroadcastContent”键在输入JSON实体中多次出现该怎么办?
Your stated requirements as I understand them (glossing over the ambiguity) would correspond to the following program, which has been tested with jq 1.4, 1.5 and the current "master" version: 据我了解,您陈述的要求(含糊不清)将与以下程序相对应,该程序已通过jq 1.4、1.5和当前的“ master”版本进行了测试:
(reduce (..| select(type == "object" and has("liveBroadcastContent"))) as $item
(false; $item | .liveBroadcastContent)) as $chanstatus
| {location:"location",
channel:"channelid",
current_id:"vId",
id_status:$chanstatus,
url:"https://youtu.be/\("vId")"}
For multiline programs such as this, it's usually much more convenient to use the -f option of jq, eg jq -f program.jq
对于这样的多行程序,通常使用jq的-f选项更加方便,例如
jq -f program.jq
If you need to accommodate jq 1.3 as well, then you'd have to handle ..
, which can be done by using dotdot
defined as follows: 如果还需要容纳jq 1.3,则必须处理
..
,这可以通过使用dotdot
定义的dotdot
来完成:
def dotdot:
recurse(if (type | . == "object" or . == "array") then .[] else empty end);
I'm not sure what your input actually looks like, but given what you've shown here, it doesn't have to be that complicated. 我不确定您输入的内容实际上是什么样子,但是鉴于您在此处显示的内容,不必那么复杂。
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: (.liveBroadcastContent? // false),
url: "https://youtu.be/vId"
}
You wanted to get the value of liveBroadcastContent
if it exists, otherwise false
and that's what precisely .liveBroadcastContent? // false
您想获取
liveBroadcastContent
的值(如果存在),否则为false
,这正是.liveBroadcastContent? // false
.liveBroadcastContent? // false
does (assuming null
is not a valid value). .liveBroadcastContent? // false
(假设null
为无效值)。
Seeing your full input object, it seems like a search result from a web api. 看到完整的输入对象,似乎是来自Web API的搜索结果。 I don't think using recursion here is really necessary.
我认为在这里使用递归并不是真正必要的。 If the goal is take each of the results and display various information about each one, I would write this filter instead.
如果目标是获取每个结果并显示有关每个结果的各种信息,那么我将改写此过滤器。 (guessing at some of the fields)
(在某些领域进行猜测)
.items[] | {
location: .channelTitle,
channel: .channelId,
current_id: .id,
id_status: (.liveBroadcastContent? // false),
url: "https://youtu.be/\(.id)"
}
If on the other hand, you were using the search results to determine whether a feed was available (based on your negative input case), I think it would be better to approach it finding the property on the list of results, rather than just the mere existence of the property anywhere. 另一方面,如果您正在使用搜索结果来确定供稿是否可用(根据您的否定输入案例),那么我认为最好在结果列表中查找属性,而不是仅查找供稿。财产仅存在于任何地方。
I would do this instead: 我会这样做:
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: ([.items[].snippet.liveBroadcastContent | select(. != null)][0] // false),
url: "https://youtu.be/vId"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.