问题 
我正在使用这个 JSON(更大的 JSON 代码的一部分): 
 
group='{ "129": { "bounds": { "left": 20, "top": 20, "width": 250, "height": 200 }, " slot”:88,“userSize”:null,“stackTabs”:true,“showThumbs”:true,“showUrls”:true,“tileIcons”:true,“catchOnce”:true,“catchRules” ;: “”, “标题”: “”, “id”: 129 } }' 
 
首先,我得到了顶级键(这里是 "129" ),它实际上可以是任何数字: 
 
键=`回声$组| jq 'keys[0]'` #“129” 
 
我想将此键更改为另一个名为 nextID 的数字,该数字是从较大的 JSON 中的另一个条目获得的: 
 
nextID=`echo $groups_meta | jq '.nextID'`#130 
 
现在问题来了。我可以使用以下过滤器更改密钥,但在我看来它相当脆弱和复杂: 
 
new_group=`回声 $group | jq --arg key $key --arg nextID $nextID 'with_entries( if .key | contains($key) then .key |= "$nextID" else .end)'` 
 
您可以看到过滤器通过搜索名称来查找键。如果以后有另一个具有相同名称的键,这可能是一个问题。那是脆弱的。这种方法看起来相当复杂;我真的很想得到这个密钥(如上面的 keys[0] )并使用它来进行更改,所有这些都在同一个过滤器中。 
 
所以我的问题是:有没有办法把这两个部分结合起来,不用搜索就能得到钥匙? 
 
更新 
 
样本输入: 
 
group='{ "129": { "bounds": { "left": 20, "top": 20, "width": 250, "height": 200 }, " slot”:88,“userSize”:null,“stackTabs”:true,“showThumbs”:true,“showUrls”:true,“tileIcons”:true,“catchOnce”:true,“catchRules” ;: “”, “标题”: “”, “id”: 129 } }' 
 
下一个 ID=130 
 
jq 命令: 
 
new_group=`回声 $group | jq --arg nexID $nextID 'filter'` 
 
预期输出: 
- echo $new_group
 
 - { "130": { "bounds": { "left": 20, "top": 20, "width": 250, "height": 200 }, "slot": 88, "userSize": null, "stackTabs": true, "showThumbs": true, "showUrls": true, "tileIcons": true, "catchOnce": true, "catchRules": "", "title": "", "id": 130 } }
 
  复制代码 
请注意,第一个键应该可以按位置寻址,例如“129”。如上所示,因为事先不知道数量。键 keys[0] 的值也设置为 id 。两者都应该使用 bash 变量“130”来设置。导入jq。 
 
更新 2 
 
使用@jq170727's 的答案,我成功地在 $nextID 之后添加了一些值更改,但是我在将同一输入中的 .title 值更改为带空格的字符串时遇到了问题: 
 
下一个ID 
 
这将引发错误: 
- title="new title"
 
 - new_group=`echo $group | jq --arg nextID $nextID --arg title $title '(keys_unsorted|first) as $i | with_entries(if .key == $i then .key=$nextID | .value.id=$nextID | .value.title=$title else . end)'`
 
  复制代码 
在 jq 命令中引用 title 变量也会产生错误。如果标题在 bash 中没有空格,则此命令有效。 
 
我是否错过了使用包含空格的变量更新值的技巧?我应该问一个新问题吗? 
 
回答 
您的原始过滤器已关闭。这是一个做你所要求的。 
 
(keys_unsorted|first) 作为 $i | with_entries(如果 .key == $i 则 .key=$nexID| .value.id=$nexID 否则 .end) 
 
bash 中的交互式示例:在线试用! 
 
您可以一次完成所有操作,而不是使用单独的调用。 
 
例如,假设完整的 json 是 
- {
 
 -   "group": {
 
 -     "129": {
 
 -       "bounds": { "left": 20, "top": 20, "width": 250, "height": 200 },
 
 -       "slot": 88, "userSize": null, "stackTabs": true, "showThumbs": true, "showUrls": true,
 
 -       "tileIcons": true, "catchOnce": true, "catchRules": "", "title": "", "id": 129
 
 -     }
 
 -   },
 
 -   "groups_meta": {
 
 -     "nextID": 130
 
 -   }
 
 - }
 
  复制代码 
你可以使用这个过滤器 
-    (.group | keys_unsorted | first) as $i
 
 -  | (.groups_meta.nextID | tostring) as $n
 
 -  | .group |= with_entries( if .key == $i then .key = $n | .value.id = $n else . end ) 
 
  复制代码 
在线尝试! 
 
这将相信从 nextID 生成的字符串不在组中。 
- nextID
 
 -  you can add something like 
 
 - | .groups_meta.nextID += 1 to the end.
 
  复制代码 
 
 
 
 |