试图编写一个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中的值。-在传递给脚本的字符串中使用空格。
发布于 2020-06-12 15:18:14
使用--arg
传递变量。做:
jq --arg key "$1" --arg value "$2" '.[$key] = $value'
备注:
#!/bin/sh
表示这是posix脚本,而不是bash。在bash脚本中使用#!/bin/bash
。function replaceValue {
是来自ksh的东西。更喜欢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]
发布于 2020-06-12 15:37:47
您不必使用--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中并污染环境,而仅仅是jq
构建所需JSON所需的环境。
若要对原始文件进行更改,请执行> tmp.json && mv tmp.json build/config.json
或更清楚地从多用包下载海绵(1)实用程序。如果存在,您可以将jq
的输出作为
| sponge build/config.json
发布于 2020-06-12 15:01:21
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是从输入中选择.version
,但是您可以为其他两个设置自己的值。我们使用双引号来允许Bash变量展开,这意味着转义JSON中的双引号。
您需要修改我上面的片段来编写脚本。
https://stackoverflow.com/questions/62346892
复制相似问题