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

时间:2018-04-21 01:44:09

标签: json bash heredoc

我有这个用于在bash脚本中声明JSON字符串:

{
    "errorCode": "UNKNOWN_ENVELOPE_RECIPIENT",
    "message": "The recipient you have identified is not a valid recipient of the specified envelope."
}

上面的heredoc有效,但我似乎无法以任何其他方式对其进行格式化,它实际上看起来就像那个哈哈。

有没有办法让命令在一行上,如下所示:

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

这样会更好,但似乎没有,显然只是因为那不是EOF的工作原理我想大声笑。

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

  1. 不需要大量逃脱字符。
  2. 允许动态插值变量。
  3. 注意:我想要使用的实际JSON有多个具有许多键/值对的动态变量。请推断。

6 个答案:

答案 0 :(得分:3)

我不是JSON人,不太了解上面讨论中“格式良好”的论点,但是,你可以使用'here-string'而不是'here-document',就像这样:

<?php

    $text = " 
    <html>
    <head>
        <title>Page Title</title>
    </head>
    <body>
         Reference site about Lorem Ipsum, giving information on its origins, as well as a random Lipsum generator.
    </body>
    </html> ";

    OR

    $text = $row['columnname'];  // Here define your database table column name.

    echo htmlspecialchars_decode($text);  

?>

希望有所帮助。

答案 1 :(得分:3)

您可以使用printf:

执行此操作
local json="$(printf '{"quicklock":"%s"}' "$my_var")"

(没关系,SO的语法突出显示在这里看起来很奇怪.Posix shell命令替换允许嵌套一级引号。)

注释(感谢Charles Duffy's comment on the question):我假设$my_var不受用户输入控制。如果是,您需要小心确保它对于JSON字符串是合法的。我强烈建议禁止使用非ASCII字符,双引号和反斜杠。如果您有jq可用,则可以在评论中使用Charles,以确保您具有格式良好的输出。

答案 2 :(得分:2)

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

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}\" }"

答案 3 :(得分:2)

为什么不使用jq?它非常适合管理字符串插值,它会破坏你的结构。

$ echo '{}' >> foo.json
$ local myvar="assigned-var"
$ jq --arg ql $myvar '.quicklock=$ql' foo.json
然后,在jq调用的另一端出现的文本可以是cat到文件或任何你想做的事情。文字看起来像这样:

{"quicklock"="assigned-var"}

答案 4 :(得分:1)

由于没有转义字符是强烈要求,这里是基于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"
}

答案 5 :(得分:1)

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

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

那就是说,这是一个相当粗略的计划,正如其他人指出的那样,如果变量包含引号字符,你就会遇到问题。