当我想将非文本文件的内容转储到终端(或文本文件)作为人类可读的值时,我可以使用od
:我可以查看具有各种类型元素的文件-有符号或无符号整数,浮点数或可打印ASCII。(您也可以将数据以各种基数打印,如十六进制或八进制,因此得名,但这不是我关心的。)
限制是,假定输入文件具有单一的统一数据类型。但是,如果事实并非如此呢?如果我有一个三元组,比如说,一个单字节的无符号值,然后是一个大小为4字节的浮点元素,然后是一个大小为2字节的有符号整数元素?即在od
术语中,u1,f4,d2
?
我希望看到这些类型的数字的三元组序列打印给我;使用任何合理的换行和字段定界惯例。假设我想要像上面那样指定我的结构体/元组格式,即逗号分隔的样式;但在具体问题上我可以灵活处理。
我可以使用shell和常见的命令行工具相对轻松地实现这一点吗?
od
命令将使用单个-t
选项(例如,在您的示例中为-t u1f4d2
)累积多种格式,并为所请求的每种类型输出一行。由于您有多个相同类型,将它们添加到-t
选项只会增加冗余信息,因此我们可以只使用代表性类型。尝试生成一些类似于描述的数据,您会得到如下内容,每个请求的类型都有一行输出:
% echo "128 255 12 3.7 -12" | perl -ne "print pack("CCCfs", split)" | od -An -tu1f4d2
128 255 12 205 204 108 64 244 255 // u1
-1.4784717e+08 -6.0981913e+31 3.57e-43 // f4
-128 -13044 27852 -3008 255 // d2
不幸的是,od
似乎试图为每行应用所请求的类型,并且由于在您的示例中,三个无符号字节导致它们后面的浮点值不从字(32位)边界开始,因此它无法正确解码浮点数。
但是,如果您的数据打包匹配单词边界,那么您可以非常接近。通过在您的三元组后插入一个额外的无符号字节:
% echo "128 255 12 255 3.7 -12" | perl -ne "print pack("CCCCfs", split)" | od -An -tu1f4d2
128 255 12 255 205 204 108 64 244 255
-1.8741855e+38 3.7 9.1819e-41 // we get the correct float
-128 -244 -13107 16492 -12 // and signed short
在这种情况下,我们可以使用更多的shell魔法来接近您所要求的
% echo "128 255 12 255 3.7 -12" | perl -ne "print pack("CCCCfs", split)" | od -An -tu1f4d2 | paste -sd ' n' | awk '{ print $1, $2, $3, $12, $18 }'
128 255 12 3.7 -12
解码命令管道:
命令 | 说明 | |
---|---|---|
echo "128 255 12 255 3.7 -12" | 以请求的形式创建一些数据(4个无符号字节,浮点数和一个有符号短数) | |
perl -ne "print pack("CCCCfs", split)" | 将它们写成二进制 | |
od -An -tu1u1u1u1fFdS | 解码二进制。od 将为每个请求的类型写一行输出:•解码为无符号字节 •解码为浮点数 •解码为有符号的短裤 | |
paste -sd ' n' | 将三行合并 | |
awk '{ print $1,$2,$3,$12,$18 }' | 从空格分隔的输出中打印选中的字段 |