我有一个像这样的 json 模板文件:
# INPUT file.json
{
"set1":{
"string1": "${VAR1}",
"string2": "${VAR2}",
(...)
}
}
脚本收集这些 VAR 值。因此,我需要获取此 json 模板并输出设置了所有变量的 json.tmp。
# OUTPUT file.json.tmp
{
"set1":{
"string1": "string1_value",
"string2": "string2_value",
(...)
}
}
我想读取该文件然后回显它,但它总是输出 tmp 文件而不设置这些变量。
VAR1=$1
VAR2=$2
# (...)
JSON_IN=`cat file.json`
echo $JSON_IN > file.json.tmp
有任何想法吗?
谢谢
答案1
这是什么envsubst
可以做的:
必须导出变量,因为它envsubst
是一个分叉进程并且不知道未导出的变量。
export VAR1=$1
export VAR2=$2
envsubst < file.json > file.json.tmp
json
请注意,如果变量包含双引号 ( "
) 或换行符等字符,这将破坏您的有效性。
答案2
使用envsubst
如果变量的值是“好的”并且不需要进行 JSON 编码,则可以方法。它还需要导出您的变量。
但是,一旦变量中有特殊值,这种情况就会崩溃:
$ jq . file
{
"set1": {
"string1": "${VAR1}",
"string2": "${VAR2}"
}
}
$ export VAR1='line 1
line 2'
$ export VAR2='"hello"'
$ envsubst <file | jq .
parse error: Invalid string: control characters from U+0000 through U+001F must be escaped at line 4, column 7
${
相反,从 JSON 文件中的值的开头和结尾删除}
,并使用剩余的字符串查找内部变量$ENV
(将环境变量作为键值对保存的对象)中的值:
$ jq '.[][] |= ( ltrimstr("${") | rtrimstr("}") | $ENV[.] )' file
{
"set1": {
"string1": "line 1\nline 2",
"string2": "\"hello\""
}
}
这.[][]
值的路径,|=
是更新运算符。因此,通过查找它们对应的环境变量的值并用这些值替换它们来更新这些值。
使用上面的代码,与现有环境变量不对应的字符串将被替换为null
:
$ jq . file
{
"set1": {
"string1": "${VAR1}",
"string2": "${VAR2}",
"string3": "${bumblebee}"
}
}
$ jq '.[][] |= ( ltrimstr("${") | rtrimstr("}") | $ENV[.] )' file
{
"set1": {
"string1": "line 1\nline 2",
"string2": "\"hello\"",
"string3": null
}
}