使用jq从JSON数组中的第n个对象中获取特定的键:值对

时间:2017-06-20 17:08:29

标签: json shell jenkins jq jenkins-api

通过curl

使用来自Jenkins构建api调用的JSON
std::condition_variable cv; //Create a CV
std::mutex lock; //Create a lock
void thread(){
        std::unique_lock<std::mutex> ulock(lock); 
        cv.wait(ulock); //Wait this thread until it is awoken
        //your code here
}
void process_packet(const byte p[]){
        if(p[0] == 0xFF)
                cv.notify_all(); //wake up all CVs 
        else
                //other stuff
}

为什么我可以{ "_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" },以及resultactions[2] failCountactions[2] skipCount来创建一个像这样的新JSON:

actions[2] totalCount

修改

我的目标是在api中更改密钥时不必重新指定密钥。我基本上不想要这个:

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

3 个答案:

答案 0 :(得分:3)

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

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

{result} + (.actions[2] | {failCount,skipCount,totalCount})

答案 1 :(得分: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"

答案 2 :(得分:0)

  

我的目标是不必在api中更改密钥时重新指定密钥。

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

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

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

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

如果您不想要一些额外字段,可以删除它们,例如如果您确实不想要&#34; _class&#34;,您可以将del(._class)添加到管道中。