是否可以不转义双引号并获得正确的 json 格式?

是否可以不转义双引号并获得正确的 json 格式?

我想使用httpie提交json数据。

如果我使用双引号并转义键周围的双引号,它就可以工作。

json="[ \
    { \
        \"count\": 3 \
    } \
]"

echo $json

[ {“计数”:3 }]

但我不想逃避。下面的复制粘贴比较容易,但是不行。

json='[ \
    { \
        "count": 3 \
    } \
]'

echo $json

[ \ { \ “计数”:3 \ } \ ]

那么,是否有可能不转义 json 键周围的双引号,从而更容易从某处复制并粘贴?

答案1

var="foo\
bar"

双引号内的序列\<newline>是特殊的,但单引号内的序列不是特殊的,并且是已删除,所以$var包含foobar.

当你在做的时候:

echo $json

您正在使用 split+glob 运算符(当您忘记引用扩展时调用的隐式运算符),也就是说, 的内容$json根据 中的字符进行拆分$IFS,并且每个单词都会生成文件名(也称为通配符)。

默认值$IFS包含空格制表符和换行符(空格、制表符和换行符也恰好在分割方面得到特殊处理,因为它们的任何序列都计数为 1,并且忽略前导和尾随序列)。例如:

var='  foo  *
bar'

echo $var

$var首先分为foo,*bar(分裂部分)并*扩展到当前目录中的非隐藏文件列表(全局部分)。

如果您想按原样显示内容(但请注意,许多echo实现可能会破坏内容),您可以编写:

$ echo "$json"
[     {         "count": 3     } ]

现在,如果您的目的是压缩间距,也许您可​​以使用 split+glob 运算符来发挥您的优势。

json='
  [
    {
      "count": 3
    }
  ]'

unset -v IFS # make sure we get a default splitting behaviour.
             # an unset -v IFS is equivalent to IFS=$' \t\n'
set -o noglob # disable the glob part

echo $json # use the split+glob operator

echo输出以空格分隔的参数,因此每个空格、制表符或换行符序列实际上都会被单个空格字符替换(前导和尾随字符除外,它们将被删除,并echo在最后添加一个换行符)。所以你会得到:

[ { "count": 3 } ]

在任何情况下,这都不会区分空格是否在引号内,因此它可能会改变 json 数据的含义(例如"foo bar"将被转换为)。"foo bar"

如果您想使用\<newline>序列来转义(删除)换行符,但保留其他空白字符,而不必转义双引号字符,则可以使用此处文档:

json=$(cat <<EOF
  [\
    {\
      "count": 3\
    }\
  ]
EOF
)
echo "$json"

这会给出:

  [    {      "count": 3    }  ]

(换行符已被删除(您可以选择保留其中一些换行符,而不在它们前面添加反斜杠),但其他空白字符保持不变)。

答案2

不需要反斜杠来继续引号内的行。在第二个示例中,反斜杠是非常有害的,因为在单引号内它们将保持原样,从而使字符串在语法上无效。只要去掉反斜杠就可以了。

相关内容