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.
3 Réponses :
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
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.
Vous pourriez envisager cette alternative à l'utilisation de |=
:
walk( if type=="object" and .name=="DB_USERNAME" then .value="new" else . end)
Pourquoi ne fusionnez-vous pas vos deux réponses?
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.