生成非法 JSON 的工具出现问题。
某些 JSON 字符串包含 00-1f 范围内的字符。所以我想将这些字符转换为\u00xx
字符串中正确转义的值。
我能做到的最好的事情是:
cat test2.json | jq -aR . | sed -e 's/\\"/"/g' -e 's/^"\(.*\)"$/\1/' | jq
解释:
jq -aR reads the data as raw input and converts
the whole thing into a single string.
This converts all control characters into
the correct form => \u00xx
sed -e 's/^"\(.*\)"$/\1/' Removes the quotes from the beginning and end.
sed -e 's/\\"/"/g' Looks for escaped quotes and removed the quotes.
jq Just makes it pretty again at the end.
Also makes sure it is valid JSON.
我发现了一些问题(但幸运的是还没有影响我)。
- 字符串中嵌入的 '\n' 未正确处理。
- 任何转义字符现在都可能是双重转义的。
- 可能还有其他我没有考虑过的事情。
一些测试数据可以通过以下方式生成:
echo -e "{ \"data\": \"XX\001YY\"}" > test2.json
然后我测试了:
cat test2.json | jq -aR . | sed -e 's/\\"/"/g' -e 's/^"\(.*\)"$/\1/' | jq
生成:
{
"data": "XX\u0001YY"
}
newline
只是注意到,当它位于字符串内部时,这不能正确处理=> '\n' => '\x0a' 。
答案1
您可以使用 perl 将所有 C0 控件替换为十六进制转义符:
perl -pe 's/([\x01-\x1f])/sprintf("\\u%04x", ord($1))/eg' < test.json
这
- 循环运行程序,最后打印结果 sed-style (
perl -pe
) - 匹配 01-1f 范围内的每个字节 (
s/([\x01-\x1f])/
...g
) - 计算字节的序数值 (
ord($1)
) sprintf("\\u%04x", ord($1))
将匹配的字节替换为(/e
)的结果
这将插入\u0001
, \u0002
, ...,\u001f
来代替匹配的字节。
它将要以相同的方式转义所有换行符,因此如果文件有未加引号的换行符,它将中断(值得注意的是,文本文件将至少有一个终止换行符,但可以在之前或之后机械删除)。在这种情况下,[\x01-\x09\x0b-\x1f]
将跳过它,但如果有则失败是引号内真正的换行符。
如果您的文件同时包含带引号和不带引号的换行符,则这种无上下文替换无法工作。您将需要一个自由的 JSON 解析器,它按原样接受文件,以便知道哪些需要转义,哪些不需要。我不确定其中之一。