![是否可以不转义双引号并获得正确的 json 格式?](https://linux22.com/image/101045/%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E4%B8%8D%E8%BD%AC%E4%B9%89%E5%8F%8C%E5%BC%95%E5%8F%B7%E5%B9%B6%E8%8E%B7%E5%BE%97%E6%AD%A3%E7%A1%AE%E7%9A%84%20json%20%E6%A0%BC%E5%BC%8F%EF%BC%9F.png)
我想使用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
不需要反斜杠来继续引号内的行。在第二个示例中,反斜杠是非常有害的,因为在单引号内它们将保持原样,从而使字符串在语法上无效。只要去掉反斜杠就可以了。