0

通过 curl 使用从 Jenkins 构建 api 调用中获取的 JSON

{
   "_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun",
   "actions" : [
       {
           "_class" : "hudson.model.CauseAction",
           "causes" : [
                {
                    "_class" : "jenkins.branch.BranchIndexingCause",
                    "shortDescription" : "Branch indexing"
                }
            ]
        },
        {
            "_class" : "hudson.model.ParametersAction",
            "parameters" : [ "..." ]
        },
        {
            "_class" : "hudson.tasks.junit.TestResultAction",
            "failCount" : 1,
            "skipCount" : 14,
            "totalCount" : 222,
            "urlName" : "testReport"
        }
    ],
    "artifacts" : [ "..."  ],
    "result" : "UNSTABLE",
    "previousBuild" : {
        "number" : 98,
        "url" : "<some Url>"
     }
}

为什么我能做到jq '{result}' <fileNameWithJSON>并得到

{ "result" : "UNSTABLE" }

但我不能做jq '{.actions[2] failCount}' <fileNameWithJSON>或其他变化,如

  • jq '{actions[2].failCount}'
  • jq '{actions[2] failCount}'
  • jq '{actions .[2].failCount}'
  • 等等

    得到{ "failCount" : "1" }

我想抓住result, 以及actions[2] failCount,actions[2] skipCountactions[2] totalCount创建一个新的 JSON,如下所示:

{ "result" : "UNSTABLE","failCount" : 1, "skipCount" : 14,"totalCount" : 222}

编辑:

我的目标是不必重新指定密钥,以防它们在 api 中发生变化。我基本上不想要这个:

{result, "failCount":.actions[2].failCount, "skipCount":.actions[2].skipCount, "totalCount": .actions[2].totalCount}
4

3 回答 3

3

jq 只能在对象文字中将直接字段从一个对象复制到另一个对象。尽管在支持这种功能的其他语言中肯定有可能,但它的编程并没有比这更深入。

如果您的目标是尽量减少属性名称的重复,您只需稍微重写过滤器。

{result} + (.actions[2] | {failCount,skipCount,totalCount})
于 2017-06-20T17:28:49.253 回答
0

{}语法是糖。当您需要一个简单的表达式时,它旨在用作快捷方式,但是当您真正想要的更有趣时,没有理由使用相同的缩短语法。

jq '
  .actions[2] as $a2 |              # assign second action to a variable
  { "result": .result,              # refer direct to original input when appropriate...
    "skipCount": $a2.skipCount,     # ...or to that variable otherwise.
    "failCount": $a2.failCount,
    "totalCount": $a2.totalCount}
' <<<"$json"
于 2017-06-20T17:28:51.650 回答
0

我的目标是不必重新指定密钥,以防它们在 api 中发生变化。

如果这是主要目标之一,您可能需要考虑以下示例的方法,该方法也不假设哪个元素.actions包含感兴趣的信息:

{ result } + (.actions[] | select(has("failCount")))

使用您的示例数据,这将产生:

{
  "result": "UNSTABLE",
  "_class": "hudson.tasks.junit.TestResultAction",
  "failCount": 1,
  "skipCount": 14,
  "totalCount": 222,
  "urlName": "testReport"
}

如果您不想要一些额外的字段,您可以删除它们,例如,如果您绝对不想要“_class”,您可以添加del(._class)到管道中。

于 2017-06-20T19:33:04.833 回答