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.