我尝试从以下形式的文件开始:
00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f
并用它生成一个 8 字节文件,其值(十六进制形式)为:
42 52 62 72 00 00 00 1f
确切的输入格式并不是一成不变的。我刚刚选择了“;”作为注释分隔符,因为它是单个字符且明确。根据传统,偏移量:和两位十六进制值的形式似乎很明显。
我怀疑最终的解决方案涉及使用sed
或awk
删除注释,然后将它们的输出通过管道传输到xxd
,但到目前为止,我的第一个实验已经失败了,我什至无法让 xxd 解析应该是最好的情况简单的文本文件。
对于我的第一次尝试,我简化了 config.src:
00: 42
01: 52
02: 62
03: 72
(暂时省略注释和隐含的零字节,并坚持使用与可打印 ASCII 相对应的值)
...然后尝试从中生成二进制文件:
xxd -r config.src config.bin
cat config.bin
我期望从和看到什么xxd config.bin
:
BRbr
和00000000: 42 52 62 72 BRbr
我最终得到的是:
无法呈现包含不可打印内容的 2 字节文件cat
,并且以下输出xxd config.bin
:00000000: 0301
所以...问题#1...我对 xxd 做错了什么,我该如何解决它(或者有更好的方法)?请记住,我确实想为每行指定一个字节值,并且非常希望能够自动跳过连续值并自动用零填充它们。
问题#2...一旦我让 xxd 解析我的文件,我怎样才能添加注释并在 xxd 看到它们之前将它们删除?
请注意,我本身并不打算使用 xxd...但这是一个共享网络服务器,我没有 root 或管理员访问权限,所以apt-get install
不是一个选项,并且从源代码编译我自己的副本也不会'不一定很容易)。
(背景信息......对于解决问题来说并不是必需的,但可以添加背景信息来说明我为什么要这样做)
我正在开发基于 Arduino 的 IoT 控制器。在过去的几周里,它的配置由硬编码值和我每隔几天重新调整用途的 DIP 开关的各种解释组成。越来越乏味了。我还没有心情实现一个合适的 UI,所以我想到了让它从我的 Web 服务器获取二进制配置 blob 到 char[] 中作为启动时的第一个动作(使我能够调整运行时配置值,而不必一路刷新板本身,这在这一点上确实是一种痛苦)。
答案1
让我们从你的开始config.src
:
$ cat config.src
00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f
将其转换为config.bin
,注释被跳过-c1
:
$ xxd -r -c1 config.src config.bin
$ xxd config.bin
00000000: 4252 6272 0000 001f BRbr....
将其转换回以下config.src
格式:
$ xxd -c1 config.bin # this is unmodified
00000000: 42 B
00000001: 52 R
00000002: 62 b
00000003: 72 r
00000004: 00 .
00000005: 00 .
00000006: 00 .
00000007: 1f .
$ xxd -c1 config.bin | awk -F '' '
{
$0=substr($0, 7) # remove 6 leading characters
$0=substr($0, 1, 6) # remove ASCII output
}
/00$/{ next } # skip hex 00
{ print $0 " ; " } # print line and empty comment
'
00: 42 ;
01: 52 ;
02: 62 ;
03: 72 ;
07: 1f ;
答案2
您可能想尝试 perl 的pack
功能。
前任。给定
$ cat config.src
00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f
然后
$ perl -ne 'm/(\d+): ([[:xdigit:]]{2})/; while($n++ < $1){print pack("x")}; print pack("H*",$2)' config.src | xxd -c1
00000000: 42 B
00000001: 52 R
00000002: 62 b
00000003: 72 r
00000004: 00 .
00000005: 00 .
00000006: 00 .
00000007: 1f .