我最终在jq中得到一个要在jq中转换为ASCII的十六进制字符串。在外面做这件事还涉及通过多个条件,这使事情变得更加复杂,并且确实会减慢解决方案的速度。
要清楚:它涉及的字符串翻译如下:
"0x4162634b6c6d" -> "AbcKlm"
剥离“ 0x”很容易(。[2:]),我在bash函数中得到了等效结果:
function h2a ()
{
while read s; do
n=0;
while [[ "$n" -lt ${#s} ]]; do
h="${s:$n:2}";
printf "\x$h";
n="$(($n+2))";
done;
done
}
但是我真的很想在本地jq中做到这一点。我找到了Rosetta JQ,但是无法转换。
感谢您的帮助!
编辑:进步,发现how to access substrings 现在,我如何转换和迭代?
答案 0 :(得分:3)
您可以使用如下功能:
def decode_hex:
("0123456789abcdef"|split("")|with_entries({key:.value, value:.key})) as $hex_map |
def decode_nybble: $hex_map[ascii_downcase];
def decode_byte: (.[0:1]|decode_nybble * 16) + (.[1:2]|decode_nybble);
def pairs: range(0;length;2) as $i | .[$i:$i+2];
[pairs|decode_byte] | implode;
然后使用它,去掉所有非十六进制字符并将字符串传递进来。
.[2:] | decode_hex
有趣的是,与数组相比,字符串的处理方式非常不同,令我惊讶。您无法直接对其进行索引或对它们执行其他类似数组的操作。通过查看上面定义$hex_map
和decode_byte
的方式,可以看出它有多尴尬。
答案 1 :(得分:0)
$ cat q6.jq
{ "b":
[(
{ "a": (split("")) }
| .a[]
| gsub ("a"; "10"; "i") | gsub ("b"; "11"; "i") | gsub ("c"; "12"; "i") | gsub ("d"; "13"; "i") | gsub ("e"; "14"; "i") | gsub ("f"; "15"; "i")
)
]
}
| { "a": [ .b as $m | range(0; $m | length; 2) | { "q" : [ ($m[.]|tonumber), ($m[(. + 1)]|tonumber) ] } ] } |
[ (.a[].q) as $b | (($b[0]) * 16) as $d | ($b[1]) as $e | ($d+$e) ] | implode
$ echo '"4162634b6c6d"' | jq -f q6.jq
"AbcKlm"
$
是的,我知道,它很丑陋,是bash函数大小的两倍,并且可以正常工作。如果可以改善:请向我们展示。
答案 2 :(得分:0)
如果需要有效的解决方案,请then带@JeffMercado的答案:
def decode_hex:
def decode: if . < 58 then .-48 elif . < 91 then .-55 else .-87 end;
def decode_byte: map(decode) | (.[0] * 16) + .[1];
def pairs: explode | range(0;length;2) as $i | [.[$i], .[$i+1]];
[pairs|decode_byte] | implode;