Подтвердить что ты не робот

Изменить json файл на bash script

Мне нужна ваша помощь для решения следующей проблемы: У меня есть файл JSON, который выглядит так:

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

как я могу добавить и удалить новый ключ (i.e "key4": "value4") на bash script? Я также вижу проблему добавления или удаления запятой в конце последнего ключа в файле перед добавлением или удалением нового.

Спасибо

4b9b3361

Ответ 1

Лучше всего использовать JSON CLI, такой как jq:

  • В системах на основе Debian, таких как Ubuntu, вы можете установить его с помощью sudo apt-get install jq
  • В macOS с установленным Homebrew (http://brew.sh/) используйте brew install jq

Примеры, основанные на следующей входной строке - вывод в stdout:

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

Удалить "ключ3":

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

Добавьте свойство "key4" со значением "value4":

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

Измените значение существующего свойства "key1" на "new-value1":

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

Спасибо, Ларс Кисов, за более надежную альтернативу:
Если вы передадите новое значение с помощью --arg, jq позаботится о правильном экранировании значения:

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

Если вы хотите обновить JSON файл на месте (с концептуальной точки зрения), используя пример удаления "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

Вы не можете заменить входной файл напрямую, поэтому результат записывается во временный файл, который заменяет входной файл в случае успеха.

Обратите внимание на -c, которая производит компактный, а не красиво напечатанный JSON.

Все параметры и команды см. В руководстве по адресу http://stedolan.github.io/jq/manual/.

Ответ 2

Не ответ для всех, но если у вас уже есть NodeJs, установленный в вашей системе, вы можете использовать его, чтобы легко манипулировать JSON.

например:

#!/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

Черт, если вам нужно только манипулировать JSON, и у вас есть node (то есть: вам действительно не нужны другие функции bash), вы можете напрямую написать script с помощью node в качестве интерпретатора

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

Ответ 3

Основываясь на ответе Ленни, мы можем использовать параметр узла -p, который оценивает данный сценарий и записывает вывод в стандартный stdout.

Использование оператора распространения для легкой модификации дает:

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