Json 我如何制作这个jq表达式,它在jq>;=1.5,版本向后兼容/正确<;1.5
在Json 我如何制作这个jq表达式,它在jq>;=1.5,版本向后兼容/正确<;1.5,json,bash,foreach,jq,Json,Bash,Foreach,Jq,在jq>=1.5的任何版本(我已经尝试过)中,都可以正常工作在jq 1.5的任何版本中: { "location": "location", "channel": "channelid", "current_id": "vId", "id_status": true, "url": "https://youtu.be/vId" } 它应该做什么: 如果输入中存在liveBroadcastContent,则在id\u状态键中输出其值 如果liveBroadcastConte
jq>=1.5的任何版本(我已经尝试过)中,都可以正常工作
在jq 1.5的任何版本中:
{
"location": "location",
"channel": "channelid",
"current_id": "vId",
"id_status": true,
"url": "https://youtu.be/vId"
}
它应该做什么:
- 如果输入中存在
liveBroadcastContent
,则在id\u状态
键中输出其值
- 如果
liveBroadcastContent
不存在:则在id\u状态
键中输出false
- 将所有其他内容输出为书面形式
实际输入:
{
"location": "location",
"channel": "channelid",
"current_id": "vId",
"id_status": true,
"url": "https://youtu.be/vId"
}
当有现场直播时,节目中会出现什么内容。
当没有直播流时,节目中会出现什么内容
因此,我认为。|.liveBroadcastContent?
是最可靠的方式,基本上可以说“如果此键出现在数据中的某个地方,请在固定格式输出数据的部分返回它的值”
既然应用程序显而易见,请注意,我知道使用其他方法,例如检查“totalResults”
的值,结合HTTP 200
,但是:
jq
的这个应用程序在其他地方可能很有用,我想把它作为一个例子来介绍
整个程序是一个共享程序,作为一次按需调用,它是更全面实现的oauth服务器应用程序的备份方法(API密钥)。有时输入数据是不同的,因此我只想递归地搜索liveBroadcastContent
编辑:只是澄清一下-这不是关于跨版本的jq
的行为(属于jq
论坛)-而是关于生成最健壮的可移植代码。我倾向于认为版本>1.5只是原谅了一个格式不好的表达式(我正在尝试解决这个问题)
您的代码段在JQ1.4中失败的原因是,foreach
仅在版本1.5中引入
我不确定您使用foreach
的程序是否与您声明的要求一致,遗憾的是,这些要求有点不清楚。例如,如果“liveBroadcastContent”键在输入JSON实体中出现多次,该怎么办
据我所知,您所述的要求(消除歧义)将对应于以下程序,该程序已通过jq 1.4、1.5和当前“主”版本的测试:
对于这样的多行程序,使用jq的-f选项通常更方便,例如jq-f program.jq
如果您还需要适应jq 1.3,那么您必须处理。
,这可以通过使用定义如下的dotdot
来完成:
我不确定你的输入实际上是什么样子的,但考虑到你在这里展示的内容,它不必那么复杂
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: (.liveBroadcastContent? // false),
url: "https://youtu.be/vId"
}
您希望获取liveBroadcastContent
的值(如果存在),否则false
,而这正是.liveBroadcastContent?//false
不存在(假设null
不是有效值)
看到完整的输入对象,它看起来像是来自web api的搜索结果。我不认为在这里使用递归是真正必要的。如果目标是获取每个结果并显示关于每个结果的各种信息,我将编写此过滤器。(猜测一些字段)
另一方面,如果您使用搜索结果来确定提要是否可用(基于您的否定输入案例),我认为更好的做法是在结果列表中查找属性,而不仅仅是在任何地方都存在该属性
我会这样做:
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: ([.items[].snippet.liveBroadcastContent | select(. != null)][0] // false),
url: "https://youtu.be/vId"
}
你不需要反斜杠;单个多行字符串可以用作jq
@chepner的筛选参数,感谢您的编辑。如果我真的这样做了,会发生什么(TLDR:jq:error:syntax error,意外的标识,在第8行:
)我认为这是由于您以前使用了两倍的反斜杠,而不是过滤器中的任何空白。我可以用“\\(“foo”)”
vs“\(“foo”)”
来重现这个错误。如果我们能看到您的输入,而不是给出这个非常简单的示例,那将更有帮助。请给我们一些更能代表您正在使用的内容。@JeffMercado-回顾性地说,我很遗憾没有包括这一点。我尽量小心不要过分夸大这个问题,因为我错误地认为我可以简单地重复它。我努力遵循这里的指导原则:-不幸的是,我没有提供足够的信息。我现在编辑了。我想知道我现在是否应该为了社区和搜索者的利益编辑这个问题。“使用jq递归搜索特定密钥的存在并将其作为新对象的一部分的可靠方法”?非常感谢您的帮助。foreach
中的INIT
似乎有一些意义。您可以使用foreach
查看您提供的两个程序与原始程序之间的差异。我最初在问题中忽略了一个真实的数据集,认为它几乎无关紧要,但实际上是程序中的数据集。如果我解决了这个问题,我会发回邮件。我为这个错误道歉。我已经相应地更新了响应,但可能我不了解需求。谢谢,这是一个非常有用的?//应用程序如果null无效,则为false
def dotdot:
recurse(if (type | . == "object" or . == "array") then .[] else empty end);
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: (.liveBroadcastContent? // false),
url: "https://youtu.be/vId"
}
.items[] | {
location: .channelTitle,
channel: .channelId,
current_id: .id,
id_status: (.liveBroadcastContent? // false),
url: "https://youtu.be/\(.id)"
}
{
location: "location",
channel: "channelid",
current_id: "vId",
id_status: ([.items[].snippet.liveBroadcastContent | select(. != null)][0] // false),
url: "https://youtu.be/vId"
}