如何在bash中创建仅包含十六进制字符而不包含空格的文件的十六进制转储?

Posted

技术标签:

【中文标题】如何在bash中创建仅包含十六进制字符而不包含空格的文件的十六进制转储?【英文标题】:How to create a hex dump of file containing only the hex characters without spaces in bash? 【发布时间】:2011-02-06 13:41:44 【问题描述】:

如何使用 bash 在 Linux 中创建二进制文件的未修改十六进制转储? odhexdump 命令都在转储中插入空格,这并不理想。

有没有办法在输出中简单地编写一个包含所有十六进制字符、减去空格或换行符的长字符串?

【问题讨论】:

另见:How to print only the hex values from hexdump without line numbers or ASCII table? 【参考方案1】:
xxd -p file

或者,如果您想在一行中全部显示:

xxd -p file | tr -d '\n'

【讨论】:

fyi 要反转这个过程:xxd -r -ps hexascii.txt 文件(可以有或没有换行符)【参考方案2】:

格式化字符串可以使 hexdump 的行为完全符合您的要求(完全没有空格,逐字节):

hexdump -ve '1/1 "%.2x"'

1/1 表示“每种格式都应用一次并占用一个字节”,"%.2x" 是实际的格式字符串,就像在 printf 中一样。在这种情况下:2 个字符的十六进制数字,如果较短则前导零。

【讨论】:

你需要一个-v 否则它会丢弃重复的字节并用星号替换它们。 我想知道 hexdump 本身是否能够(仅)将换行符附加到输出的末尾。(; echo 的明显附加使其无法用作 bash 别名) 我的别名:alias to_hex="hexdump -ve '1/1 \"%.2x\"' && echo" 迭代次数和字节数默认为1,所以1/1可以省略,留下hexdump -ve '"%.2x"' @mykhal,如果您知道输出中的字节数,这是可能的。假设您使用 hexdump 仅输出 13 个前字节:hexdump -n 13 -e '13/1 "%.2x" "\n"'【参考方案3】:

这似乎取决于od的版本细节。在 OSX 上,使用这个:

od -t x1 -An file |tr -d '\n '

(打印为十六进制字节类型,没有地址。当然,随后空格被删除。)

【讨论】:

我也会在这个上下文中添加-v,否则它会跳过*的重复。【参考方案4】:

Perl 单行:

perl -e 'local $/; print unpack "H*", <>' file

【讨论】:

已验证。匹配“xxd -p 文件 | tr -d '\n'”。 fyi 要反转这个过程: perl -e 'local $/;打印包 "H*", ' file “本地$/”是不必要的。 更新到最后一条评论:“pack”不需要“local $/”。对于解包,您需要它,但也可以输入“undef $/”。 $/ 是行分隔符(默认 NL)。 undefined 将其置于 slurp 模式。因此,在字符串上下文中引用的 会拉取整个二进制文件而不会将其解析为行。 替代形式:perl -e 'print unpack "H*", join("", )' 【参考方案5】:

其他答案更可取,但对于纯 Bash 解决方案,我已修改 my answer here 中的脚本,以便能够输出表示文件内容的连续十六进制字符流。 (它的正常模式是模拟hexdump -C。)

【讨论】:

【参考方案6】:

我认为这是最广泛支持的版本(仅需要 POSIX 定义的 trod 行为):

cat "$file" | od -v -t x1 -A n | tr -d ' \n'

这使用od 将每个字节打印为没有地址的十六进制而不跳过重复的字节,并使用tr 删除输出中的所有空格和换行符。请注意,这里甚至不会发出尾随换行符。 (cat 有意允许多核处理,其中cat 可以等待文件系统,而od 仍在处理先前读取的部分。单核用户可能希望用&lt; "$file" od ... 替换它以节省启动一个额外的进程。)

【讨论】:

【参考方案7】:

此代码生成一个“纯”十六进制转储字符串,它运行速度比所有 给出的其他示例。 它已经在 1GB 填充二进制零和所有换行符的文件上进行了测试。 它不依赖于数据内容,读取 1MB 记录而不是行。

perl -pe 'BEGIN$/=\1e6 $_=unpack "H*"'

数十次计时测试表明,对于 1GB 文件,以下这些其他方法较慢。 所有测试都运行将输出写入文件,然后通过校验和进行验证。 测试了三个 1GB 输入文件:所有字节、所有二进制零和所有 LF。

hexdump -ve '1/1 "%.2x"'                    #  ~10x  slower
od -v -t x1 -An | tr -d "\n "               #  ~15x  slower
xxd -p | tr -d \\n                          #   ~3x  slower
perl -e 'local \$/; print unpack "H*", <>'  # ~1.5x  slower
- this also slurps the whole file into memory

要反转这个过程:

perl -pe 'BEGIN$/=\1e6 $_=pack "H*",$_'

【讨论】:

【参考方案8】:

tldr;

$ od -t x1 -A n -v <empty.zip | tr -dc '[:xdigit:]' && echo 
504b0506000000000000000000000000000000000000
$

说明:

使用od 工具打印单个十六进制字节 (-t x1) --- 没有地址偏移 (-A n) 并且没有省略重复的“组”(-v) --- 来自empty.zip,它有被重定向到标准输入。将其传送到tr,它会删除(-d)十六进制字符集('[:xdigit:]')的补码(-c)。您可以选择打印尾随换行符 (echo),就像我在此处所做的那样,将输出与下一个 shell 提示符分开。

参考资料:

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html https://pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html

【讨论】:

【参考方案9】:

您可以为此目的使用 Python:

python -c "print(open('file.bin','rb').read().hex())"

...file.bin 是您的文件名。

说明:

    rb(读取二进制)模式打开file.bin。 读取内容(返回为bytes 对象)。 使用bytes 方法.hex(),它返回不带空格或换行符的十六进制转储。 打印输出。

【讨论】:

以上是关于如何在bash中创建仅包含十六进制字符而不包含空格的文件的十六进制转储?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查字符串是否包含子字符串,而不是在Bash中

如何在 OBIEE 中创建仅限于报告数据的提示?

如何在bash中将空格替换为新行[重复]

如何在 bash 中的任意数量的空格之后搜索和替换字符串?

如何在 bash shell 中将一个字符串拆分为多个字符串,至少用一个空格分隔?

包含在字符串中的 Bash-scramble 字符