Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用jq从变量更改json对象和字段值_Bash_Jq - Fatal编程技术网

Bash 使用jq从变量更改json对象和字段值

Bash 使用jq从变量更改json对象和字段值,bash,jq,Bash,Jq,我想使用jq在LinuxBashShell中指定的变量修改以下json var1="red" var2="european.flowers" var3="european_vegetables" var4="20" 我的json: { "plants": { "flowers.small": { "colour": "", "age": "", "vegetables": { "root": "", "height": "" } }

我想使用jq在LinuxBashShell中指定的变量修改以下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":""}}}}
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
命令

cat myjson.json|jq --arg v "$var1" '.plants.["flowers.small"].colour = [$v]' -c
结果是:

{"plants":{"flowers.small":{"colour":"${var1}","age":"","vegetables":{"root":"","height":""}}}}
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:error:syntax error,意外的“[”,需要格式或QQSTRING_START(Unix shell引用问题?),第1行:
.植物。[“花.小”]。颜色=$v
jq:1编译错误
我的jq版本是:jq-1.5-1-a5b5cbe

如何重命名字段并从变量中为键设置值? 使用jq版本甚至可以做到这一点吗?

使用
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
var1=“红色”var2=“欧洲花卉”var3=“欧洲蔬菜”var4=“20”
jq--arg var1“$var1”--arg var2“$var2”--arg var3“$var3”--arg var4“$var4”'
#为我们希望在输入中看到的字段设置变量
“花.小”如$plant\u tmpl|
“蔬菜”作为$cat_tmpl|
#更改字段内的内容,我们稍后将重命名*然后*重命名这些字段
.plants[$plant\u tmpl].颜色=$var1|
.plants[$plant\u tmpl][$cat\u tmpl]。高度=$var4|
如果$var3==$cat\u tmpl,则为.else
#var3不是“蔬菜”(模板值),所以我们需要重命名它
.plants[$plant\u tmpl][$var3]=.plants[$plant\u tmpl][$cat\u tmpl]|
del(.plants[$plant\u tmpl][$cat\u tmpl])
结束|
如果$var2==$plant\u tmpl,则为.else
.plants[$var2]=.plants[$plant\u tmpl]|
del(.plant[$plant\u tmpl])
结束

“我怀疑这与你想要的非常接近:

#!/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食谱,以了解有关使用jq作为模板引擎的建议:

精简版 如果您的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

仅供参考,避免将输入文件名直接传递给
jq
或使用
更有效。我使用cat只是为了在tryping时为管道键入便利,谢谢你的建议。对我来说,如何处理json并不重要,我只想将jq作为处理json的组件传递的字符串不太容易出错。