试图写一个bash脚本来替换JSON文件中的值,但我们遇到了环境变量包含空格的问题。
给定一个原始的JSON文件,我们想运行一个命令来更新其中的一些变量。
{
"version": "base",
"myValue": "to be changed",
"channelId": 0
}
我们想运行一个命令来更新其中的一些变量,所以在我们运行之后。
CHANNEL_ID=1701 MY_VALUE="new value" ./test.sh
JSON文件应该是这样的
{
"version": "base",
"myValue": "new value",
"channelId": 1701
}
我们的脚本目前是这样的
#!/bin/sh
echo $MY_VALUE
echo $CHANNEL_ID
function replaceValue {
if [ -z $2 ]; then echo "Skipping $1"; else jq --argjson newValue \"${2}\" '. | ."'${1}'" = $newValue' build/config.json > tmp.json && mv tmp.json build/config.json; fi
}
replaceValue channelId ${CHANNEL_ID}
replaceValue myValue ${MY_VALUE}
在上面的脚本中,所有的值都被字符串代替了 而字符串在空格处被截断了。我们一直在这个问题和替换完全停止工作的代码版本之间交替。
这肯定是一个扩展的问题,但我们很想知道,我们如何能够:-用字符串和值替换JSON中的值.-在我们传递给脚本的字符串中使用空格。
传递变量,并在变量中加入 --arg
做。
jq --arg key "$1" --arg value "$2" '.[$key] = $value'
注意:
#!/bin/sh
表示这是 正面罩 脚本,而不是bash。脚本,而不是bash。#!/bin/bash
在bash脚本中。function replaceValue {
是来自ksh shell的东西。更喜欢 replaceValue() {
来声明函数. Bash过时的、已被废弃的句法.--argjson
通过一个 json格式的 参数,而不是字符串。使用 --arg
为,。\"${2}\"
不引用 $2
扩充--它只对字符串进行追加,并在后缀上加上 "
. 因为扩写没有引用,所以要进行拆词 是 执行,这会导致您的输入在为 jq
.. |
在 jq
这就像 echo $(echo $(echo)))
. 你可以 jq '. | . | . | . | . | .'
无限次地做------它传递的是同样的东西。只要写出你想做的事情就可以了。做。
#!/bin/bash
echo "$MY_VALUE"
echo "$CHANNEL_ID"
replaceValue() {
if [ -z "$2" ]; then
echo "Skipping $1"
else
jq --arg key "$1" --arg value "$2" '.[$key] = $value' build/config.json > tmp.json &&
mv tmp.json build/config.json
fi
}
replaceValue channelId "${CHANNEL_ID}"
replaceValue myValue "${MY_VALUE}"
@编辑 替换 ."\($key)"
更容易 .[$key]
你不需要惹 --arg
或 --argjson
将环境变量导入到 jq
的上下文。它可以很好地自行读取环境。你不需要单独的脚本,只需要在调用 jq
CHANNEL_ID=1701 MY_VALUE="new value" \
jq '{"version": "base", myValue: env.MY_VALUE, channelId: env.CHANNEL_ID}' build/config.json
请注意,在上面的案例中,变量需要用到 不 在全球范围内输出,而只是在本地输出到 jq
命令,这样就可以避免将多个变量导出到shell中而污染环境。这允许你不将多个变量导出到shell中,不污染环境,而只将需要的变量导出到shell中。jq
来构建所需的JSON。
要想将修改回到原始文件,请执行以下操作。> tmp.json && mv tmp.json build/config.json
或更清楚地下载 海绵(1) 实用性 更多 包的输出。如果存在,你可以用管道输出 jq
作为
| sponge build/config.json
jq允许你建立新的对象。
MY_VALUE=foo;
CHANNEL_ID=4
echo '{
"version": "base",
"myValue": "to be changed",
"channelId": 0
}' | jq ". | {\"version\": .version, \"myValue\": \"$MY_VALUE\", \"channelId\": $CHANNEL_ID}"
这个 .
选择整个输入,而输入的(|
)到一个新对象的构建(用 "标示 "表示)。{}
). 对于版本选择 .version
的输入,但你可以为其他两个变量设置自己的值。我们使用双引号来允许Bash变量的扩展,也就是在JSON中转义双引号。
你需要改编我上面的片段来进行脚本化。