使用jq in循环更新json(数组元素)中的值

使用jq in循环更新json(数组元素)中的值,json,jq,Json,Jq,我有一个带有数组的输入json文件。我需要更新每个数组元素中的两个值(版本和日期)。我可以想出下面的脚本,但需要帮助。我已硬编码版本和日期以简化脚本 input.json [ { "svcname": "svc1", "repo": "https://repo.mycom.org/repocontext/svc1-list", "ver": "0.1", "date": "2019-11-05" }, { "svcname": "svc1",

我有一个带有数组的输入json文件。我需要更新每个数组元素中的两个值(版本和日期)。我可以想出下面的脚本,但需要帮助。我已硬编码版本和日期以简化脚本

input.json

[
  {
    "svcname": "svc1",
    "repo": "https://repo.mycom.org/repocontext/svc1-list",
    "ver": "0.1",
    "date": "2019-11-05"
  },
  {
    "svcname": "svc1",
    "repo": "https://repo.mycom.org/repocontext/svc1-list",
    "ver": "0.1",
    "date": "2019-12-21"
  }
]
脚本:

#!/bin/bash
set +x
injson=input.json
updatedjson=$(jq .[] ${injson})

services=$(cat ${injson} | jq '.[] | .svcname' | tr -d \")
i=1
for svc in $services; do 

        echo "==>$svc"
        echo "======> input json=${updatedjson}"
        echo "======> update ver=${i}"
        updatedjson=$(echo ${updatedjson} | jq ". | select( .name ==\"$svc\").ver=\"$i\"" | jq . )
        svcdate="2020-01-$i"
        echo "======> update date=$svcdate"
        updatedjson=$(echo ${updatedjson} | jq ". | select( .name ==\"$svc\").date=\"$svcdate\"" | jq . )
        echo "============================================"
        echo
        i=`expr $i + 1`

done

echo "======= write to file ====="
echo ${updatedjson}
echo ${updatedjson} | jq . > outjson.json

您没有使用
jq
的真正功能。在循环中显示的内容,迭代所有JSON对象可以简单地简化为一个
reduce()
构造,这是
jq
中的
for
循环,给定一个初始值并递增运行过滤器

jq 'reduce range(0, length) as $d (.; (.[$d].ver = ($d+1|tostring)) | (.[$d].date = "2020-01-\($d+1)")) '
对其工作原理的简要说明

  • 范围表达式返回一个列表,其中的数字从0到数组中对象的长度。对于给定的输入,它将生成分配给
    d
    0,1
  • 给定整个JSON的输入值
    reduce
    表达式通过设置
    $d
    索引的每个对象中的值来运行。因此
    [$d].ver
    引用第0个索引中的
    ver
    字段。这将以增量方式进行,直到处理完所有对象
  • 使用
    [$d]修改日期字段的方法与此相同。日期
    的值字符串前缀为(YYYY-MM-),并相应地设置日期

  • 现在我尝试使用实际变量(代替硬编码值),但遇到了jq sytax错误echo${updatedjson}}jq“将范围(0,长度)减少为(.;(............................................................................................................选择(在第1行:=======非常感谢@Inian,我从您的代码中学到了很多