【发布时间】:2011-02-06 13:41:44
【问题描述】:
如何使用 bash 在 Linux 中创建二进制文件的未修改十六进制转储? od 和 hexdump 命令都在转储中插入空格,这并不理想。
有没有办法在输出中简单地编写一个包含所有十六进制字符、减去空格或换行符的长字符串?
【问题讨论】:
如何使用 bash 在 Linux 中创建二进制文件的未修改十六进制转储? od 和 hexdump 命令都在转储中插入空格,这并不理想。
有没有办法在输出中简单地编写一个包含所有十六进制字符、减去空格或换行符的长字符串?
【问题讨论】:
xxd -p file
或者,如果您想在一行中全部显示:
xxd -p file | tr -d '\n'
【讨论】:
格式化字符串可以使 hexdump 的行为完全符合您的要求(完全没有空格,逐字节):
hexdump -ve '1/1 "%.2x"'
1/1 表示“每种格式都应用一次并占用一个字节”,"%.2x" 是实际的格式字符串,就像在 printf 中一样。在这种情况下:2 个字符的十六进制数字,如果较短则前导零。
【讨论】:
-v 否则它会丢弃重复的字节并用星号替换它们。
; echo 的明显附加使其无法用作 bash 别名)
alias to_hex="hexdump -ve '1/1 \"%.2x\"' && echo"
hexdump -ve '"%.2x"'
hexdump -n 13 -e '13/1 "%.2x" "\n"'
这似乎取决于od的版本细节。在 OSX 上,使用这个:
od -t x1 -An file |tr -d '\n '
(打印为十六进制字节类型,没有地址。当然,随后空格被删除。)
【讨论】:
-v,否则它会跳过*的重复。
Perl 单行:
perl -e 'local $/; print unpack "H*", <>' file
【讨论】:
其他答案更可取,但对于纯 Bash 解决方案,我已修改 my answer here 中的脚本,以便能够输出表示文件内容的连续十六进制字符流。 (它的正常模式是模拟hexdump -C。)
【讨论】:
我认为这是最广泛支持的版本(仅需要 POSIX 定义的 tr 和 od 行为):
cat "$file" | od -v -t x1 -A n | tr -d ' \n'
这使用od 将每个字节打印为没有地址的十六进制而不跳过重复的字节,并使用tr 删除输出中的所有空格和换行符。请注意,这里甚至不会发出尾随换行符。 (cat 有意允许多核处理,其中cat 可以等待文件系统,而od 仍在处理先前读取的部分。单核用户可能希望用< "$file" od ... 替换它以节省启动一个额外的进程。)
【讨论】:
此代码生成一个“纯”十六进制转储字符串,它运行速度比所有 给出的其他示例。 它已经在 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*",$_'
【讨论】:
$ 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 提示符分开。
【讨论】:
您可以为此目的使用 Python:
python -c "print(open('file.bin','rb').read().hex())"
...file.bin 是您的文件名。
说明:
rb(读取二进制)模式打开file.bin。bytes 对象)。bytes 方法.hex(),它返回不带空格或换行符的十六进制转储。【讨论】: