5
votes

Modification du tableau de valeur de clé dans JSON jq

Dans le cas où j'ai un json original ressemblant à ce qui suit:

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

Et je voudrais modifier la valeur de la clé correspondante comme suit:

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

J'ai eu la sortie

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

Mais je veux plus comme une modification sur place ou l'ensemble json de l'original avec une nouvelle valeur modifiée, comme ceci:

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

Est-il possible de faire avec jq ou toute autre solution connue?

Merci.

Mise à jour

Pour tous ceux qui souhaitent modifier des valeurs multiples, voici l'approche que j'utilise

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

Je pense qu'il devrait y avoir un moyen plus concis, mais cela semble fonctionner correctement.


0 commentaires

3 Réponses :


4
votes

Il suffit d'attribuer le chemin, si vous utilisez | = , par exemple

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

Sortie:

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


1 commentaires

Merci. Cette solution semble la plus évidente à la question que je me posais. J'ajoute également pour modifier les valeurs multiples en fonction de votre réponse, veuillez consulter la section mise à jour dans la réponse.



2
votes

Vous pourriez envisager cette alternative à l'utilisation de |=:

walk( if type=="object" and .name=="DB_USERNAME" 
      then .value="new" else . end)


1 commentaires

Pourquoi ne fusionnez-vous pas vos deux réponses?



2
votes

Voici une solution sans sélection utilisant |=:

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

Éviter select dans l'expression sur la LHS de | = rend la solution plus robuste wrt la version de jq utilisée.


0 commentaires