jq在空白处截断ENV变量。

问题描述 投票:0回答:1

试图写一个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中的值.-在我们传递给脚本的字符串中使用空格。

json bash jq
1个回答
2
投票

传递变量,并在变量中加入 --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.
  • 记住要引用变量扩展。
  • 使用 http:/shellcheck.net 来检查你的脚本。
  • . |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]


3
投票

你不需要惹 --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

-2
投票

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中转义双引号。

你需要改编我上面的片段来进行脚本化。

© www.soinside.com 2019 - 2024. All rights reserved.