У меня есть файл json test.json следующего формата:
{
"environments":
{
"egress": [
]
}
}
Я хочу добавить объекты в выходное поле с несколькими значениями переменных. Я написал скрипт bash test.sh с фрагментом кода ниже:
egress_port='[80,443]'
egress_value='[test,test1]'
egress_protocol='[http,https]'
# IFS=','
echo $egress_port
echo $egress_value
echo $egress_protocol
cat test.json |
jq --argjson port "$egress_port" \
--argjson value "$egress_value" \
--argjson protocol "$egress_protocol" \
'.environments.egress = ([$port, $value, $protocol] | transpose |
map ({port: .[0], type: "external", value: .[1], protocol: .[2]}))'
Я хочу, чтобы json обновлялся в формате ниже:
{
"environments":
{
"egress": [
{
"port": "80",
"type": "external",
"value": "test",
"protocol": "http"
},
{
"port": "443",
"type": "external",
"value": "test1",
"protocol": "https"
}
]
}
}
Когда я запускаю его, он выдает ошибку:
jq: invalid JSON text passed to --argjson
Может ли кто-нибудь помочь мне здесь?
Строка read -a port_array <<< "$egress_port"
не имеет никакого смысла, если значения уже сохранены в массиве. Каков ваш точный вариант использования? Известны ли вашему скрипту порты и протоколы или они читаются извне?
Начните с массивов JSON, а не массивов bash
для входных данных.
egress_ports='[80, 44]'
egress_values='["test", "test1"]'
egress_protocols='["http", "https"]'
Они будут переданы в качестве аргументов непосредственно фильтру jq
, из которого вы
[[80, 443], ["test", "test1"], ["http", "https"]]
[[80, "test", "http"], [443, "test1", "https"]]
|=
) этот окончательный массив непосредственно с .environments.egress
.jq --argjson ports "$egress_ports" \
--argjson values "$egress_values" \
--argjson protocols "$egress_protocols" \
'.environments.egress = ([$ports, $values, $protocols] | transpose |
map ({port: .[0], type: "external", value: .[1], protocol: .[2]}))' test.json
Если вы хотите использовать настоящие массивы Bash, вам нужно будет выполнить цикл:
ports=(80 443)
values=(test test1)
protocols=(http https)
json=$(< test.json)
for i in "${!ports[@]}"; do
json=$(
echo "$json" \
| jq --arg port "${ports[i]}" \
--arg value "${values[i]}" \
--arg protocol "${protocols[i]}" \
'.environments.egress += [
{$port, $value, $protocol, type: "external"}
]'
)
done
После этого переменная json
содержит
{
"environments": {
"egress": [
{
"port": "80",
"value": "test",
"protocol": "http",
"type": "external"
},
{
"port": "443",
"value": "test1",
"protocol": "https",
"type": "external"
}
]
}
}
Спасибо @glenn за ваш ответ. Я тоже пробовал это. Но он возвращается пустым, когда я повторяю $json. `ports=(80 443)values=(test test1)protocols=(http https) json=$(< test.json) for i in "${!ports[@]}"; do json=$( echo "$json" \ | jq --arg port "${ports[i]}" \ --arg value "${values[i]}" \ --arg протокол "${protocols[ i]}" \ '.environments.egress += [ {$port, $value, $protocol, type: "external"} ]' ) Done echo $json ` ** sh test.sh возвращает пустую строку. **
Спасибо @glenn. Я запустил его с помощью bash test.sh, и он вернул заполненный json. Еще раз спасибо!!!
Не создавайте сценарий jq, используя расширение переменных. Если
$value_array
содержит"
, созданный таким образом скрипт не является синтаксически допустимым иjq
не может его запустить. Передайте значения сценарию в качестве аргументов, используя--arg
или--argjson
. Подробности смотрите в документацииjq
: jqlang.github.io/jq/manual/#invoking-jq