如何使用jq将JSON中的ID替换为递增计数器?
问题描述
现有如下结构的JSON文件:
{ "version": "2.0", "stage" : { "objects" : [ { "foo" : 1100, "bar" : false, "id" : "56a983f1-8111-4abc-a1eb-263d41cfb098" }, { "foo" : 1100, "bar" : false, "id" : "6369df4b-90c4-4695-8a9c-6bb2b8da5976" }], "bish" : "#FFFFFF" }, "more": "abcd" }
需要将其中stage.objects数组内每个对象的id字段(原GUID格式)替换为从1开始的递增整数,其余内容保持不变,预期输出如下:
{ "version": "2.0", "stage" : { "objects" : [ { "foo" : 1100, "bar" : false, "id" : 1 }, { "foo" : 1100, "bar" : false, "id" : 2 }], "bish" : "#FFFFFF" }, "more": "abcd" }
目前已能用.stage.objects[].id |= 1将所有id设为固定整数,但无法实现递增效果,尝试过map、reduce等方法但未成功。
解决方案
可以通过两种方式实现需求,以下是具体的jq命令及解释:
方法一:利用数组索引转换
.stage.objects |= (to_entries | map(.value.id = .key + 1) | map(.value))
步骤解释:
.stage.objects |=:定位到目标数组并准备修改它to_entries:把数组转成[{key: 索引值, value: 原数组元素}, ...]的结构,数组第一个元素的key为0,第二个为1,以此类推map(.value.id = .key + 1):遍历每个键值对,将原元素的id设为key+1,让ID从1开始递增map(.value):把处理后的键值对转回原数组元素结构,去掉多余的key字段
方法二:用计数器变量实现
.stage.objects |= ([$i=0] | map(($i += 1) as $new_id | .id = $new_id))
步骤解释:
[$i=0]:初始化计数器变量$i为0map(($i += 1) as $new_id | .id = $new_id):遍历数组时,每次让$i自增1作为新ID,赋值给当前元素的id字段
内容的提问来源于stack exchange,提问作者aspen
相关产品推荐
相关产品推荐

