首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >jq在空白后截断ENV变量

jq在空白后截断ENV变量
EN

Stack Overflow用户
提问于 2020-06-12 14:57:42
回答 3查看 769关注 0票数 2

试图编写一个bash脚本来替换JSON文件中的值,我们遇到了包含空格的环境变量的问题。

给出一个原始JSON文件。

代码语言:javascript
运行
复制
{
  "version": "base",
  "myValue": "to be changed",
  "channelId": 0
}

我们希望运行一个命令来更新其中的一些变量,以便在我们运行之后:

代码语言:javascript
运行
复制
CHANNEL_ID=1701 MY_VALUE="new value" ./test.sh

JSON应该如下所示:

代码语言:javascript
运行
复制
{
  "version": "base",
  "myValue": "new value",
  "channelId": 1701
}

目前,我们的脚本如下所示:

代码语言:javascript
运行
复制
#!/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中的值。-在传递给脚本的字符串中使用空格。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-12 15:18:14

使用--arg传递变量。做:

代码语言:javascript
运行
复制
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创建参数时在空白空间上被分割。
  • 记住引用变量展开。
  • 使用http://shellcheck.net检查脚本。
  • . |jq中没有任何意义,它就像echo $(echo $(echo)))。您可以jq '. | . | . | . | . | .'无限次地这样做--它通过相同的事情。写下你想做的事。

做:

代码语言:javascript
运行
复制
#!/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]

票数 2
EN

Stack Overflow用户

发布于 2020-06-12 15:37:47

您不必使用--arg--argjson来将环境变量导入到jq的上下文中。它可以很好地单独读取环境。您不需要单独使用脚本,只需在调用jq的同时设置值即可。

代码语言:javascript
运行
复制
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的输出作为

代码语言:javascript
运行
复制
| sponge build/config.json
票数 3
EN

Stack Overflow用户

发布于 2020-06-12 15:01:21

jq允许您构建新对象:

代码语言:javascript
运行
复制
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中的双引号。

您需要修改我上面的片段来编写脚本。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62346892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档