Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 我如何制作这个jq表达式,它在jq>;=1.5,版本向后兼容/正确<;1.5_Json_Bash_Foreach_Jq - Fatal编程技术网

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"
    }