web-dev-qa-db-fra.com

changer le fichier json par le script bash

J'ai besoin de votre aide pour résoudre le problème suivant: J'ai un fichier JSON qui ressemble à ceci:

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

comment puis-je ajouter et supprimer une nouvelle clé (i.e "key4": "value4") par le script bash? Je vois aussi le problème d'ajouter ou de supprimer une virgule à la fin de la dernière clé du fichier avant d'ajouter ou de supprimer la nouvelle.

Merci

46
user3155074

Votre meilleur choix consiste à utiliser un CLI JSON tel que jq = :

  • Sur les systèmes basés sur Debian tels que Ubuntu, vous pouvez l’installer via Sudo apt-get install jq
  • Sur macOS, avec Homebrew ( http://brew.sh/ ) installé, utilisez brew install jq

Exemples basés sur la chaîne d'entrée suivante - la sortie est vers stdout:

jsonStr='{ "key1": "value1", "key2": "value2", "key3": "value3" }'

Supprimer "key3":

jq 'del(.key3)' <<<"$jsonStr"

Ajouter la propriété "key4" avec la valeur "value4":

jq '. + { "key4": "value4" }' <<<"$jsonStr"

Remplacez la valeur de la propriété existante "key1" par "new-value1":

jq '.key1 = "new-value1"' <<<"$jsonStr"

Une alternative plus robuste merci, Lars Kiesow :
Si vous transmettez la nouvelle valeur avec --arg, jq s’occupe d’échapper correctement à la valeur:

jq '.key1 = $newVal' --arg newVal '3 " of rain' <<<"$jsonStr"

Si vous souhaitez mettre à jour un fichier JSON à la place (conceptuellement) , en utilisant l'exemple de suppression de "key3":

# Create test file.
echo '{ "key1": "value1", "key2": "value2", "key3": "value3" }' > test.json

# Remove "key3" and write results back to test.json (recreate it with result).
jq -c 'del(.key3)' test.json > tmp.$$.json && mv tmp.$$.json test.json

Vous ne pouvez pas remplacer le fichier d'entrée directement, le résultat est donc écrit dans un fichier temporaire qui remplace le fichier d'entrée en cas de succès.

Noter la -c, qui produit un JSON compact plutôt que joliment imprimé.

Pour toutes les options et commandes , voir le manuel à http://stedolan.github.io/jq/manual/ .

85
mklement0

Ce n'est pas la solution pour tout le monde, mais si vous avez déjà des NodeJ installés sur votre système, vous pouvez les utiliser pour manipuler facilement JSON.

par exemple:

#!/usr/bin/env bash
jsonFile=$1;

node > out_${jsonFile} <<EOF
//Read data
var data = require('./${jsonFile}');

//Manipulate data
delete data.key3
data.key4 = 'new value!';

//Output data
console.log(JSON.stringify(data));

EOF

Heck, si vous seulement avez besoin de manipuler JSON et que vous avez un noeud (c'est-à-dire: vous n'avez pas vraiment besoin d'une autre fonctionnalité bash), vous pouvez directement écrire un script en utilisant node comme interprète:

#! /usr/bin/env node
var data = require('./'+ process.argv[2]);
/*manipulate*/
console.log(JSON.stringify(data));
24
Lenny Markus

En nous appuyant sur la réponse de Lenny, nous pouvons utiliser l'option -p du nœud, qui évalue le script donné et écrit le résultat dans stdout.

L'utilisation de l'opérateur spread pour une modification facile donne:

node -p "JSON.stringify({...require('./data.json'), key4: 'value4'}, null, 2)" > data.json
0
Ben Chislett