为什么来自heredoc的JSON内容不可解析?

为什么来自heredoc的JSON内容不可解析?

我有一个 JSON 片段。

以下不起作用:

VALUE=<<PERSON
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"  
}
PERSON
echo -n "$VALUE" | python -m json.tool

结果是:

无法解码 JSON 对象

jq对ie做同样的事情

echo -n "$VALUE" | jq '.'

没有输出。

以下内容具有相同的行为:

VALUE=<<PERSON
'{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"  
}'
PERSON
echo -n "$VALUE" | python -m json.tool

回复:

无法解码 JSON 对象

但以下工作有效:

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"
}'
echo -n "$VALUE" | jq '.'
echo -n "$VALUE" | python -m json.tool

答案1

VALUE=<<PERSON
some data
PERSON

echo "$VALUE"

无输出。

此处文档是重定向,您无法重定向到变量。

解析命令行时,重定向是在与变量分配不同的步骤中处理的。因此,您的命令相当于(注意空格)

VALUE= <<PERSON
some data
PERSON

也就是说,它为您的变量分配一个空字符串,然后将标准输入从此处字符串重定向到命令(但没有命令,所以什么也没有发生)。

注意

<<PERSON
some data
PERSON

是有效的,原样

<somefile

只是没有任何命令的标准输入流可以设置为包含数据,所以它就丢失了。

但这会起作用:

VALUE=$(cat <<PERSON
some data
PERSON
)

在这里,接收此处文档的命令是cat,并将其复制到标准输出。这就是通过命令替换分配给变量的内容。

在你的情况下,你可以使用

python -m json.tool <<END_JSON
JSON data here
END_JSON

无需采取将数据存储在变量中的额外步骤。


研究像这样的工具也可能是值得的jo使用正确的编码创建 JSON 数据:

例如:

jo type=account customer_id=1234 [email protected] random_data="some^Wdata"

...其中^W是文字Ctrl+W字符,将输出

{"type":"account","customer_id":1234,"customer_email":"[email protected]","random_data":"some\u0017data"}

所以问题中的命令可以写成

jo type=account customer_id=1234 [email protected] |
python -m json.tool

答案2

因为您的定界文档未设置该变量:

$ VALUE=<<PERSON  
> {    
>   "type": "account",  
>   "customer_id": "1234",  
>   "customer_email": "[email protected]",  
> }  
> PERSON
$ echo "$VALUE" 

$

如果你想使用定界文档为变量赋值,你需要类似:

$ read -d '' -r VALUE <<PERSON  
{    
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "[email protected]",  
}   
PERSON

答案3

这是因为您定义与 JSON 一起使用的此处文档的方式是错误的。你需要把它用作

VALUE=$(cat <<EOF
{  
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "[email protected]",  
}
EOF
)

并且应该printf "$VALUE"按预期转储 JSON。

答案4

此处文档和变量不能很好地混合,或者至少不能以这种方式混合。您可以...

将heredoc作为应用程序的标准输入传递

python -m json.tool <<PERSON  
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]",
}
PERSON

或者…

将多行文本存储在 shell 变量中

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]",
}'

我使用单引号来避免转义内部双引号的需要。当然你也可以使用双引号,例如如果你需要扩展参数:

VALUE="{
  \"type\": \"account\",
  \"customer_id\": ${ID},
  \"customer_email\": \"${EMAIL}\",
}"

然后您可以稍后使用该变量值。

echo -n "$VALUE" | python -m json.tool

相关内容