如何在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 中创建二进制文件的未修改十六进制转储? od
和 hexdump
命令都在转储中插入空格,这并不理想。
有没有办法在输出中简单地编写一个包含所有十六进制字符、减去空格或换行符的长字符串?
【问题讨论】:
另见: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*", '其他答案更可取,但对于纯 Bash 解决方案,我已修改 my answer here 中的脚本,以便能够输出表示文件内容的连续十六进制字符流。 (它的正常模式是模拟hexdump -C
。)
【讨论】:
【参考方案6】:我认为这是最广泛支持的版本(仅需要 POSIX 定义的 tr
和 od
行为):
cat "$file" | od -v -t x1 -A n | tr -d ' \n'
这使用od
将每个字节打印为没有地址的十六进制而不跳过重复的字节,并使用tr
删除输出中的所有空格和换行符。请注意,这里甚至不会发出尾随换行符。 (cat
有意允许多核处理,其中cat
可以等待文件系统,而od
仍在处理先前读取的部分。单核用户可能希望用< "$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中创建仅包含十六进制字符而不包含空格的文件的十六进制转储?的主要内容,如果未能解决你的问题,请参考以下文章