#arrays #json #bash #append #jq
#массивы #json #bash #добавить #jq
Вопрос:
Мне очень сложно пытаться итеративно добавлять новые значения к вновь созданному массиву / файлу JSON из того же скрипта bash. Рассмотрим следующий простой фрагмент сценария:
echo "Enter name: "
read name
echo "Enter Car Model: "
read car
echo "Enter Colour: "
read colour
echo
jq -n --arg name "$name" --arg car "$car" --arg colour "$colour" '{"profiles":[{"name": $name, "car": $car, "colour": $colour}]}' > model.json
echo
cat model.json | jq .
Это выводит:
Enter name:
Joe
Enter Car Model:
BMW
Enter Colour:
Red
{
"profiles": [
{
"name": "Joe",
"car": "BMW",
"colour": "Red"
}
]
}
Я хочу, чтобы в конечном итоге это делалось примерно так, динамически:
Enter name:
Joe
Enter Car Model:
BMW
Enter Colour:
Red
{
"profiles": [
{
"name": "Joe",
"car": "BMW",
"colour": "Red"
},
{
"name": "Peter",
"car": "Nissan",
"colour": "White"
}
]
}
и т.д…
Я понимаю, что мне нужно будет использовать цикл после первого набора записей key:value, но тогда как я буду добавлять к вновь созданному файлу model.json, а не переопределять начальные значения через jq в скрипте bash?
Большое спасибо
Ответ №1:
Чтобы добавить объект, вы можете использовать идиому:
.profiles = [...]
Из-за дружественного способа обработки jq null
вышеуказанное также будет работать изначально.
Кстати, вы можете сокращать пары ключ-значение, такие как
"name": $name
только к имени переменной:
$name
Пример
Для единообразия может иметь смысл предварительно заполнить model.json null
, например
echo null > model.json
Затем вы можете вызывать jq равномерно (без опции -n), например
jq --arg name "$name" --arg car "$car" --arg colour "$colour" '
.profiles = [{ $name, $car, $colour}]
' model.json | sponge model.json
Предостережение: перезапись входного файла с использованием sponge
без принятия мер предосторожности имеет свои риски, хотя в этом случае они кажутся небольшими.
Комментарии:
1. Нравится это?
jq -n --arg name "$name" --arg car "$car" --arg colour "$colour" '.profiles = [{$name, $car, $colour}]' > model.json
Поэтому, когда я добавляю свой цикл между командой jq и первым набором вопросов и ответов, вышеуказанное работает, но не добавляется. Просто переопределяет первый набор значений.2. Даже если я передам вышеизложенное с
| .profiles = [{$name, $car, $colour}]'
помощью возвращает тот же набор значений: « { «профили»: [ { «имя»: «Пол», «автомобиль»: «Датсон», «цвет»: «Коричневый» }, { «имя»: «Пол», «автомобиль»: «Datson», «color»: «Brown» } ] } « Дважды вводим последнюю запись.3. Вы должны отказаться от этой
-n
опции при чтении из model.json4. Спасибо, пик. Я использовал описанный вами метод, и, к сожалению, код по-прежнему выводит один набор значений (последний набор записей, которые я ввел). Независимо от того, сколько раз я ввожу значения через цикл, выводится только один набор. Я вижу логику в приведенном выше коде, но не уверен, где я ошибаюсь.
5. Вы уверены, что удалили параметр -n? Возможно, вам следует сначала попробовать самый простой случай, не используя sponge. Добавьте
debug
операторы jq, чтобы увидеть, что происходит.
Ответ №2:
Использовал метод, описанный выше, и до сих пор не добавляет: ie.
Enter name:
Joe
Enter Car Model:
BMW
Enter Colour:
Blue
Add a new entry? (y/n): y
Enter name:
Paul
Enter Car Model:
Nissan
Enter Colour:
Black
Add a new entry? (y/n): n
{
"profiles": [
{
"name": "Paul",
"car": "Nissan",
"colour": "Black"
}
]
}