如何将blob拆分为Byte Array在shell脚本中?

时间:2014-06-23 05:24:00

标签: bash postgresql shell blob psql

我在postgresql数据库中有一个blob。已经插入了C结构。

struct temp {
uint64_t a,
uint64_t b,
uint64_t c
};

现在我在shell中编写q查询以进行检索。

select resource,.....,blob_column from rtable where rId is=1

我从数据库中得到了blob的结果。结果是

x00911ee3561ac801cb0783462586cf01af00000000000000    

但是现在在shell脚本中我需要迭代它并在控制台上显示结果。尝试过不同的东西,如敬畏,分裂,转换,转换功能,但没有什么能帮助我。

有人能告诉我如何阅读这个十六进制字符串并取回整数?

1 个答案:

答案 0 :(得分:2)

这对程序员的折磨是否有点冒犯?我无法想象你为什么要这样做。尤其是因为你的struct-as-a-blob可能会受到填充和对齐的影响,这些填充和对齐因编译器和编译器以及平台而异。即便如此,由于字节序差异,它在架构之间也会有所不同。至少你使用了固定宽度类型。

假设你只关心little-endian,你的编译器不会添加任何填充或对齐(可能只有3个64位字段的结构),这是可能的。这不是一个好主意。

我首选的方法是使用一些struct的Python代码,例如

python - "x00911ee3561ac801cb0783462586cf01af00000000000000" <<__END__
import sys
import struct
print "{} {} {}".format(*struct.unpack('@QQQ', sys.argv[1][1:].decode("hex")))
__END__

因为它甚至可以使用适当的修饰符处理字节顺序和打包,并且您可以轻松地在shell脚本中使用输出。

如果这不方便/不合适,那么在bash中也是可能的,这绝对是可怕的。对于little-endian,unpadded / packed-unaligned:

解码每个值(改编自https://stackoverflow.com/a/3678208/398670):

$ x=00911ee3561ac801
$ echo $(( 16#${x:14:2}${x:12:2}${x:10:2}${x:8:2}${x:6:2}${x:4:2}${x:2:2}${x:0:2} ))

所以,完整的交易:

x=x00911ee3561ac801cb0783462586cf01af00000000000000
uint64_dec() {
    echo $(( 16#${1:14:2}${1:12:2}${1:10:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}${1:0:2} ))
}
uint64_dec ${x:1:16}
uint64_dec ${x:17:16}
uint64_dec ${x:33:16}

产生

128381549860000000
130470408871937995
175

现在,我觉得很脏,需要去洗。我强烈建议如下:

CREATE TYPE my_struct AS (a numeric, b numeric, c numeric);

然后使用my_struct而不是bytea字段。或者只使用三个numeric列。您不能使用bigint,因为Pg没有64位无符号整数。