代码之家  ›  专栏  ›  技术社区  ›  zdk

修改json jq中的键值数组

  •  3
  • zdk  · 技术社区  · 6 年前

    在这种情况下,我有一个原始的JSON,如下所示:

    {
      "taskDefinition": {
        "containerDefinitions": [
          {
            "name": "web",
            "image": "my-image",
            "environment": [
              {
                "name": "DB_HOST",
                "value": "localhost"
              },
              {
                "name": "DB_USERNAME",
                "value": "user"
              }
            ]
          }
        ]
      }
    }
    

    我想就地修改匹配键的值,如下所示:

    jq '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="DB_USERNAME") | .value="new"' json

    我得到了输出

    {
      "name": "DB_USERNAME",
      "value": "new"
    }
    

    但是我想要更像是就地修改,或者是修改原始值的整个JSON,比如:

    {
          "taskDefinition": {
            "containerDefinitions": [
              {
                "name": "web",
                "image": "my-image",
                "environment": [
                  {
                    "name": "DB_HOST",
                    "value": "localhost"
                  },
                  {
                    "name": "DB_USERNAME",
                    "value": "new"
                  }
                ]
              }
            ]
          }
        }
    

    有可能吗 jq 或者任何已知的解决方法?

    谢谢您。

    更新的

    对于任何想要编辑多值的人, 这是我使用的方法

    JQ=""
    for e in DB_HOST=rds DB_USERNAME=xxx; do
        k=${e%=*}
        v=${e##*=}
        JQ+="(.taskDefinition.containerDefinitions[0].environment[] | select(.name==\"$k\") | .value) |= \"$v\" | "
    done
    
    jq '${JQ%??}' json
    

    我认为应该有更简洁的方法,但这似乎很管用。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Thor    6 年前

    如果您使用 |= ,例如

    jq '
      (.taskDefinition.containerDefinitions[0].environment[] | 
       select(.name=="DB_USERNAME") | .value) |= "new"
    ' infile.json
    

    输出:

    {
      "taskDefinition": {
        "containerDefinitions": [
          {
            "name": "web",
            "image": "my-image",
            "environment": [
              {
                "name": "DB_HOST",
                "value": "localhost"
              },
              {
                "name": "DB_USERNAME",
                "value": "new"
              }
            ]
          }
        ]
      }
    }
    
        2
  •  2
  •   peak    6 年前

    您可能会考虑使用此替代方法 |= :

    walk( if type=="object" and .name=="DB_USERNAME" 
          then .value="new" else . end)
    
        3
  •  2
  •   peak    6 年前

    这里有一个自由选择的解决方案,使用 |= :

    .taskDefinition.containerDefinitions[0].environment |=
      map(if .name=="DB_USERNAME" then .value = "new"
          else . end)
    

    避免 select 在的lhs表达式中 = 使解决方案更为强大的w.r.t.使用的JQ版本。