json 将heredoc声明压缩到bash中的一行?

lfapxunr  于 2023-02-17  发布在  其他
关注(0)|答案(6)|浏览(102)

我有一个在bash脚本中声明JSON字符串的代码:

local my_var="foobar"
   local json=`cat <<EOF
  {"quicklock":"${my_var}"}
EOF`

上面的heredoc工作,但我似乎不能格式化它的任何其他方式,它字面上看起来完全一样,哈哈。
有没有办法让命令在一行中,像这样:

local json=`cat <<EOF{"quicklock":"${my_var}"}EOF`

这将是这么多更好,但似乎不需要,显然只是因为这不是如何EOF的工作原理,我猜哈哈。

我正在寻找一种在文件中声明JSON的简便方法:

1.不需要大量的转义字符。
1.它允许变量的动态插值。

**注意:**我想使用的实际JSON有多个动态变量,这些动态变量有许多键/值对。请外推。

2ic8powd

2ic8powd1#

我不是一个JSON爱好者,不太理解上面讨论中的“格式良好”参数,但是,您可以使用“here-string”而不是“here-document”,如下所示:

my_var="foobar"
json=`cat <<<{\"quicklock\":\"${my_var}\"}`
v64noz0r

v64noz0r2#

为什么不使用jq呢?它在管理字符串插值方面非常好,而且它会使你的结构变得松散。

$ echo '{}' >> foo.json
$ declare myvar="assigned-var"
$ jq --arg ql "$myvar" '.quicklock=$ql' foo.json

调用jq的另一端输出的文本可以cat到一个文件中,或者做任何你想做的事情。文本看起来像这样:

{"quicklock": "assigned-var"}
hs1rzwqc

hs1rzwqc3#

您可以使用printf来执行此操作:

local json="$(printf '{"quicklock":"%s"}' "$my_var")"

(不要介意SO的语法高亮在这里看起来很奇怪,Posix shell命令替换允许嵌套一层引号。)
注意(感谢查尔斯达菲的评论的问题):我假设$my_var不受用户输入的控制。如果是这样,您需要小心确保它对于JSON字符串是法律的的。我强烈建议禁止非ASCII字符、双引号和反斜杠。如果您有jq可用,您可以像Charles在注解中提到的那样使用它,以确保您有格式良好的输出。

4ioopgfo

4ioopgfo4#

您可以定义自己的helper函数来解决缺少bash语法的情况:

function begin() { eval echo $(sed "${BASH_LINENO[0]}"'!d;s/.*begin \(.*\) end.*/\1/;s/"/\\\"/g' "${BASH_SOURCE[0]}"); }

然后您可以按如下方式使用它。

my_var="foobar"

json=$(begin { "quicklock" : "${my_var}" } end)

echo "$json"

此片段显示所需的输出:

{ "quicklock" : "foobar" }

这只是一个概念验证。你可以用任何你想要的方式来定义你的语法(比如用自定义EOF字符串结束输入,正确地转义无效字符)。例如,由于Bash允许函数标识符使用非字母数字字符,所以可以定义这样的语法:

json=$(/ { "quicklock" : "${my_var}" } /)

此外,如果放宽第一个条件(转义字符),普通赋值将很好地解决这个问题:

json="{ \"quicklock\" : \"${my_var}\" }"
0tdrvxhp

0tdrvxhp5#

使用shell的字符串自然连接如何?如果连接${mybar}而不是插入它,就可以避免转义,并在一行中获得所有内容:

my_var1="foobar"
my_var2="quux"
json='{"quicklock":"'${my_var1}'","slowlock":"'$my_var2'"}'

也就是说,这是一个相当粗糙的方案,正如其他人所指出的,如果变量包含引号字符,就会出现问题。

lf5gs5x2

lf5gs5x26#

由于没有转义字符是一个强要求,因此这里有一个基于here-doc的解决方案:

#!/bin/bash

my_var='foobar'

read -r -d '' json << EOF
{
    "quicklock": "$my_var"
}
EOF

echo "$json"

它将给予与我提到的第一个解决方案相同的输出。
如果您将第一个EOF放在双引号内,请务必小心:

read -r -d '' json << "EOF"

$my_var不会被视为变量,而是被视为纯文本,因此您将得到以下输出:

{
        "quicklock": "$my_var"
}

相关问题