使用jq从JSON中提取UTF未编码的二进制数据

时间:2018-01-13 12:54:34

标签: json utf-8 binary hex jq

假设我有一个带有编码为UTF代码点的0xb7字节的JSON:

{"key":"_\u00b7_"}

如果我用jq提取“key”的值,它保持这个字节的utf8编码为“c2 b7”:

$ echo '{"key":"_\u00b7_"}' | ./jq '.key' -r | xxd
0000000: 5fc2 b75f 0a                             _.._.

是否有任何jq命令从此JSON中提取解码的“5f b7 5f”字节序列?

我可以使用像iconv这样的额外工具解决这个问题,但这有点难看:

$ echo '{"key":"_\u00b7_"}' | ./jq '.key' -r \
      | iconv -f utf8 -t utf32le \
      | xxd -ps | sed -e 's/000000//g' | xxd -ps -r \
      | xxd
0000000: 5fb7 5f0a                                _._.

2 个答案:

答案 0 :(得分:1)

def hx:
  def hex: [if . < 10 then 48 + . else  55 + . end] | implode ;
  tonumber | "\(./16 | floor | hex)\(. % 16 | hex)";

{"key":"_\u00b7_"} | .key | explode | map(hx)

产生

["5F","B7","5F"]

&#34;原始字节&#34; (警告经纪人

由于jq仅支持UTF-8字符串,因此您必须使用一些外部工具来获取&#34;原始字节&#34;。也许这更接近你想要的东西:

jq -nrj '{"key":"_\u00b7_"} | .key' | iconv -f utf-8 -t ISO8859-1

这会产生三个字节。

这是一个没有iconv的解决方案:

jq -nrj '{"key":"_\u00b7_"} | .key' | php -r 'print utf8_decode(readline());'

答案 1 :(得分:1)

<强>交替

解决jq之外的字符编码方案:

虽然你不想要额外的工具,iconvhexdump确实很容易获得 - 当我要求管道的某些部分完全时,我常常依靠iconv我知道,hexdump当我想控制那些部分的表示格式时。

所以另一种选择是:

jq -njr '{"key":"_\u00b7_"} | .key' | iconv -f utf8 -t UTF-32LE | hexdump -ve '1/1 "%.X"'

结果:

5FB75F