我想使用在Linux bash shell中使用jq指定的变量来修改以下json。
var1="red"
var2="european.flowers"
var3="european_vegetables"
var4="20"
我的json:
{
"plants": {
"flowers.small": {
"colour": "",
"age": "",
"vegetables": {
"root": "",
"height": ""
}
}
}
}
我想使用jq中的变量修改json:
{
"plants": {
"${var2}": {
"colour": "${var1}",
"age": "",
"${var3}": {
"root": "",
"height": "${var4}"
}
}
}
}
我正在尝试仅通过变量设置字段值:
命令:
cat myjson.json|jq '.plants["flowers.small"].colour = "${var1}"' -c
结果是:
{"plants":{"flowers.small":{"colour":"${var1}","age":"","vegetables":{"root":"","height":""}}}}
命令:
cat myjson.json|jq --arg v "$var1" '.plants.["flowers.small"].colour = [$v]' -c
结果是:
jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
.plants.["flowers.small"].colour = $v
jq: 1 compile error
我的jq版本是:jq-1.5-1-a5b5cbe
如何重命名字段并从变量中设置键的值? 使用jq版本甚至可以做到吗?
答案 0 :(得分:1)
我怀疑这与您想要的很接近:
#!/bin/bash
var1="red"
var2="european.flowers"
var3="european_vegetables"
var4="20"
jq --arg var1 "$var1" \
--arg var2 "$var2" \
--arg var3 "$var3" \
--arg var4 "$var4" '
{"${var1}": $var1, "${var2}": $var2, "${var3}": $var3, "${var4}": $var4} as $dict
| walk( if type == "string" and $dict[.] then $dict[.]
elif type=="object" then with_entries(if $dict[.key] then .key |= $dict[.] else . end)
else . end)' template.json
这种通用方法是可以的,但是您可能需要查看jq Cookbook,以获取有关将jq用作模板引擎的建议:https://github.com/stedolan/jq/wiki/Cookbook#using-jq-as-a-template-engine
如果您的jq支持$ARGS
,则可以使用上面的简化版本:
jq --arg '${var1}' "$var1" \
--arg '${var2}' "$var2" \
--arg '${var3}' "$var3" \
--arg '${var4}' "$var4" '
$ARGS.named as $dict
| walk( if type == "string" and $dict[.] then $dict[.]
elif type=="object" then with_entries(if $dict[.key] then .key |= $dict[.] else . end)
else . end)' template.json
答案 1 :(得分:0)
jq
作为模板引擎如果您不是真的需要input.json
作为单独的文件,则很容易做的就是将整个模板定义为jq表达式:
var1="red"
var2="european.flowers"
var3="european_vegetables"
var4="20"
jq -n --arg var1 "$var1" --arg var2 "$var2" --arg var3 "$var3" --arg var4 "$var4" '
{
"plants": {
"\($var2)": {
"colour": $var1,
"age": "",
"\($var3)": {
"root": "",
"height": $var4
}
}
}
}'
作为输出发出:
{
"plants": {
"european.flowers": {
"colour": "red",
"age": "",
"european_vegetables": {
"root": "",
"height": "20"
}
}
}
}
如果您确实要要重命名现有密钥,请考虑以下方法。在模板字段中使用jq变量不是强制性的,但这确实使以后更改代码更容易:
var1="red"; var2="european.flowers"; var3="european_vegetables"; var4="20"
jq --arg var1 "$var1" --arg var2 "$var2" --arg var3 "$var3" --arg var4 "$var4" '
# set variables for the fields we expect to see in our input
"flowers.small" as $plant_tmpl |
"vegetables" as $cat_tmpl |
# change things inside fields we will later rename *before* we rename those fields
.plants[$plant_tmpl].colour = $var1 |
.plants[$plant_tmpl][$cat_tmpl].height = $var4 |
if $var3 == $cat_tmpl then . else
# var3 is not "vegetables" (templated value), so we need to rename it
.plants[$plant_tmpl][$var3] = .plants[$plant_tmpl][$cat_tmpl] |
del(.plants[$plant_tmpl][$cat_tmpl])
end |
if $var2 == $plant_tmpl then . else
.plants[$var2] = .plants[$plant_tmpl] |
del(.plants[$plant_tmpl])
end
' <<'EOF'
{
"plants": {
"flowers.small": {
"colour": "",
"age": "",
"vegetables": {
"root": "",
"height": ""
}
}
}
}
EOF